Repository: QuantumLeaps/Super-Simple-Tasker Branch: main Commit: 41d0d219a2c0 Files: 659 Total size: 13.5 MB Directory structure: gitextract_kj309970/ ├── .gitignore ├── .vscode/ │ └── settings.json ├── 3rd_party/ │ ├── CMSIS/ │ │ ├── Include/ │ │ │ ├── cmsis_armcc.h │ │ │ ├── cmsis_armclang.h │ │ │ ├── cmsis_armclang_ltm.h │ │ │ ├── cmsis_ccs.h │ │ │ ├── cmsis_compiler.h │ │ │ ├── cmsis_gcc.h │ │ │ ├── cmsis_iccarm.h │ │ │ ├── cmsis_version.h │ │ │ ├── core_armv81mml.h │ │ │ ├── core_armv8mbl.h │ │ │ ├── core_armv8mml.h │ │ │ ├── core_cm0.h │ │ │ ├── core_cm0plus.h │ │ │ ├── core_cm1.h │ │ │ ├── core_cm23.h │ │ │ ├── core_cm3.h │ │ │ ├── core_cm33.h │ │ │ ├── core_cm35p.h │ │ │ ├── core_cm4.h │ │ │ ├── core_cm7.h │ │ │ ├── core_sc000.h │ │ │ ├── core_sc300.h │ │ │ ├── mpu_armv7.h │ │ │ ├── mpu_armv8.h │ │ │ └── tz_context.h │ │ ├── LICENSE.txt │ │ └── README.txt │ ├── ek-tm4c123gxl/ │ │ ├── README.txt │ │ ├── TM4C123GH6PM.h │ │ ├── arm/ │ │ │ └── startup_TM4C123GH6PM.s │ │ ├── gnu/ │ │ │ ├── ek-tm4c123gxl.ld │ │ │ └── startup_TM4C123GH6PM.c │ │ ├── gpio.h │ │ ├── iar/ │ │ │ └── startup_TM4C123GH6PM.s │ │ ├── rom.h │ │ ├── sysctl.h │ │ ├── system_TM4C123GH6PM.c │ │ └── system_TM4C123GH6PM.h │ ├── nucleo-c031c6/ │ │ ├── README.txt │ │ ├── arm/ │ │ │ └── startup_stm32c031xx.s │ │ ├── gnu/ │ │ │ ├── nucleo-c031c6.ld │ │ │ └── startup_stm32c031xx.c │ │ ├── iar/ │ │ │ └── startup_stm32c031xx.s │ │ ├── stm32c031xx.h │ │ ├── stm32c0xx.h │ │ ├── system_stm32c0xx.c │ │ └── system_stm32c0xx.h │ ├── nucleo-h743zi/ │ │ ├── README.txt │ │ ├── arm/ │ │ │ └── startup_stm32h743xx.s │ │ ├── gnu/ │ │ │ ├── nucleo-h743zi.ld │ │ │ └── startup_stm32h743xx.c │ │ ├── iar/ │ │ │ └── startup_stm32h743xx.s │ │ ├── stm32h743xx.h │ │ ├── stm32h7xx.h │ │ ├── system_stm32h7xx.c │ │ └── system_stm32h7xx.h │ └── nucleo-l053r8/ │ ├── README.txt │ ├── arm/ │ │ └── startup_stm32l053xx.s │ ├── gnu/ │ │ ├── nucleo-l053r8.ld │ │ └── startup_stm32l053xx.c │ ├── iar/ │ │ └── startup_stm32l053xx.s │ ├── stm32l053xx.h │ ├── stm32l0xx.h │ ├── system_stm32l0xx.c │ ├── system_stm32l0xx.c.pll │ └── system_stm32l0xx.h ├── FreeRTOS-comparison/ │ ├── CMakeLists.txt │ ├── GitHub-FreeRTOS-Kernel-Home.url │ ├── History.txt │ ├── LICENSE.md │ ├── Quick_Start_Guide.url │ ├── README.md │ ├── croutine.c │ ├── event_groups.c │ ├── examples/ │ │ ├── blinky/ │ │ │ ├── FreeRTOSConfig.h │ │ │ ├── armclang/ │ │ │ │ ├── nucleo-l053r8.uvoptx │ │ │ │ └── nucleo-l053r8.uvprojx │ │ │ ├── blinky.c │ │ │ ├── blinky.h │ │ │ ├── bsp.h │ │ │ ├── bsp_nucleo-l053r8.c │ │ │ └── main.c │ │ └── blinky_button/ │ │ ├── FreeRTOSConfig.h │ │ ├── armclang/ │ │ │ ├── nucleo-l053r8.uvoptx │ │ │ └── nucleo-l053r8.uvprojx │ │ ├── blinky1.c │ │ ├── blinky3.c │ │ ├── blinky_button.h │ │ ├── bsp.h │ │ ├── bsp_nucleo-l053r8.c │ │ ├── button2a.c │ │ ├── button2b.c │ │ └── main.c │ ├── include/ │ │ ├── FreeRTOS.h │ │ ├── StackMacros.h │ │ ├── atomic.h │ │ ├── croutine.h │ │ ├── deprecated_definitions.h │ │ ├── event_groups.h │ │ ├── list.h │ │ ├── message_buffer.h │ │ ├── mpu_prototypes.h │ │ ├── mpu_wrappers.h │ │ ├── portable.h │ │ ├── projdefs.h │ │ ├── queue.h │ │ ├── semphr.h │ │ ├── stack_macros.h │ │ ├── stdint.readme │ │ ├── stream_buffer.h │ │ ├── task.h │ │ └── timers.h │ ├── list.c │ ├── manifest.yml │ ├── portable/ │ │ ├── ARMClang/ │ │ │ └── Use-the-GCC-ports.txt │ │ ├── ARMv8M/ │ │ │ ├── ReadMe.txt │ │ │ ├── copy_files.py │ │ │ ├── non_secure/ │ │ │ │ ├── ReadMe.txt │ │ │ │ ├── port.c │ │ │ │ ├── portable/ │ │ │ │ │ ├── GCC/ │ │ │ │ │ │ ├── ARM_CM23/ │ │ │ │ │ │ │ ├── portasm.c │ │ │ │ │ │ │ └── portmacro.h │ │ │ │ │ │ ├── ARM_CM23_NTZ/ │ │ │ │ │ │ │ ├── portasm.c │ │ │ │ │ │ │ └── portmacro.h │ │ │ │ │ │ ├── ARM_CM33/ │ │ │ │ │ │ │ ├── portasm.c │ │ │ │ │ │ │ └── portmacro.h │ │ │ │ │ │ ├── ARM_CM33_NTZ/ │ │ │ │ │ │ │ ├── portasm.c │ │ │ │ │ │ │ └── portmacro.h │ │ │ │ │ │ ├── ARM_CM55/ │ │ │ │ │ │ │ └── portmacro.h │ │ │ │ │ │ └── ARM_CM85/ │ │ │ │ │ │ └── portmacro.h │ │ │ │ │ └── IAR/ │ │ │ │ │ ├── ARM_CM23/ │ │ │ │ │ │ ├── portasm.s │ │ │ │ │ │ └── portmacro.h │ │ │ │ │ ├── ARM_CM23_NTZ/ │ │ │ │ │ │ ├── portasm.s │ │ │ │ │ │ └── portmacro.h │ │ │ │ │ ├── ARM_CM33/ │ │ │ │ │ │ ├── portasm.s │ │ │ │ │ │ └── portmacro.h │ │ │ │ │ ├── ARM_CM33_NTZ/ │ │ │ │ │ │ ├── portasm.s │ │ │ │ │ │ └── portmacro.h │ │ │ │ │ ├── ARM_CM55/ │ │ │ │ │ │ └── portmacro.h │ │ │ │ │ └── ARM_CM85/ │ │ │ │ │ └── portmacro.h │ │ │ │ ├── portasm.h │ │ │ │ └── portmacrocommon.h │ │ │ └── secure/ │ │ │ ├── ReadMe.txt │ │ │ ├── context/ │ │ │ │ ├── portable/ │ │ │ │ │ ├── GCC/ │ │ │ │ │ │ ├── ARM_CM23/ │ │ │ │ │ │ │ └── secure_context_port.c │ │ │ │ │ │ └── ARM_CM33/ │ │ │ │ │ │ └── secure_context_port.c │ │ │ │ │ └── IAR/ │ │ │ │ │ ├── ARM_CM23/ │ │ │ │ │ │ └── secure_context_port_asm.s │ │ │ │ │ └── ARM_CM33/ │ │ │ │ │ └── secure_context_port_asm.s │ │ │ │ ├── secure_context.c │ │ │ │ └── secure_context.h │ │ │ ├── heap/ │ │ │ │ ├── secure_heap.c │ │ │ │ └── secure_heap.h │ │ │ ├── init/ │ │ │ │ ├── secure_init.c │ │ │ │ └── secure_init.h │ │ │ └── macros/ │ │ │ └── secure_port_macros.h │ │ ├── CCS/ │ │ │ ├── ARM_CM3/ │ │ │ │ ├── port.c │ │ │ │ ├── portasm.asm │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CM4F/ │ │ │ │ ├── port.c │ │ │ │ ├── portasm.asm │ │ │ │ └── portmacro.h │ │ │ ├── ARM_Cortex-R4/ │ │ │ │ ├── port.c │ │ │ │ ├── portASM.asm │ │ │ │ └── portmacro.h │ │ │ └── MSP430X/ │ │ │ ├── data_model.h │ │ │ ├── port.c │ │ │ ├── portext.asm │ │ │ └── portmacro.h │ │ ├── CMakeLists.txt │ │ ├── Common/ │ │ │ └── mpu_wrappers.c │ │ ├── GCC/ │ │ │ ├── ARM_CA53_64_BIT/ │ │ │ │ ├── port.c │ │ │ │ ├── portASM.S │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CA53_64_BIT_SRE/ │ │ │ │ ├── port.c │ │ │ │ ├── portASM.S │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CA9/ │ │ │ │ ├── port.c │ │ │ │ ├── portASM.S │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CM0/ │ │ │ │ ├── port.c │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CM23/ │ │ │ │ ├── non_secure/ │ │ │ │ │ ├── port.c │ │ │ │ │ ├── portasm.c │ │ │ │ │ ├── portasm.h │ │ │ │ │ ├── portmacro.h │ │ │ │ │ └── portmacrocommon.h │ │ │ │ └── secure/ │ │ │ │ ├── secure_context.c │ │ │ │ ├── secure_context.h │ │ │ │ ├── secure_context_port.c │ │ │ │ ├── secure_heap.c │ │ │ │ ├── secure_heap.h │ │ │ │ ├── secure_init.c │ │ │ │ ├── secure_init.h │ │ │ │ └── secure_port_macros.h │ │ │ ├── ARM_CM23_NTZ/ │ │ │ │ └── non_secure/ │ │ │ │ ├── port.c │ │ │ │ ├── portasm.c │ │ │ │ ├── portasm.h │ │ │ │ ├── portmacro.h │ │ │ │ └── portmacrocommon.h │ │ │ ├── ARM_CM3/ │ │ │ │ ├── port.c │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CM33/ │ │ │ │ ├── non_secure/ │ │ │ │ │ ├── port.c │ │ │ │ │ ├── portasm.c │ │ │ │ │ ├── portasm.h │ │ │ │ │ ├── portmacro.h │ │ │ │ │ └── portmacrocommon.h │ │ │ │ └── secure/ │ │ │ │ ├── secure_context.c │ │ │ │ ├── secure_context.h │ │ │ │ ├── secure_context_port.c │ │ │ │ ├── secure_heap.c │ │ │ │ ├── secure_heap.h │ │ │ │ ├── secure_init.c │ │ │ │ ├── secure_init.h │ │ │ │ └── secure_port_macros.h │ │ │ ├── ARM_CM33_NTZ/ │ │ │ │ └── non_secure/ │ │ │ │ ├── port.c │ │ │ │ ├── portasm.c │ │ │ │ ├── portasm.h │ │ │ │ ├── portmacro.h │ │ │ │ └── portmacrocommon.h │ │ │ ├── ARM_CM3_MPU/ │ │ │ │ ├── port.c │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CM4F/ │ │ │ │ ├── port.c │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CM4_MPU/ │ │ │ │ ├── port.c │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CM55/ │ │ │ │ ├── non_secure/ │ │ │ │ │ ├── port.c │ │ │ │ │ ├── portasm.c │ │ │ │ │ ├── portasm.h │ │ │ │ │ ├── portmacro.h │ │ │ │ │ └── portmacrocommon.h │ │ │ │ └── secure/ │ │ │ │ ├── secure_context.c │ │ │ │ ├── secure_context.h │ │ │ │ ├── secure_context_port.c │ │ │ │ ├── secure_heap.c │ │ │ │ ├── secure_heap.h │ │ │ │ ├── secure_init.c │ │ │ │ ├── secure_init.h │ │ │ │ └── secure_port_macros.h │ │ │ ├── ARM_CM55_NTZ/ │ │ │ │ └── non_secure/ │ │ │ │ ├── port.c │ │ │ │ ├── portasm.c │ │ │ │ ├── portasm.h │ │ │ │ ├── portmacro.h │ │ │ │ └── portmacrocommon.h │ │ │ ├── ARM_CM7/ │ │ │ │ ├── ReadMe.txt │ │ │ │ └── r0p1/ │ │ │ │ ├── port.c │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CM85/ │ │ │ │ ├── non_secure/ │ │ │ │ │ ├── port.c │ │ │ │ │ ├── portasm.c │ │ │ │ │ ├── portasm.h │ │ │ │ │ ├── portmacro.h │ │ │ │ │ └── portmacrocommon.h │ │ │ │ └── secure/ │ │ │ │ ├── secure_context.c │ │ │ │ ├── secure_context.h │ │ │ │ ├── secure_context_port.c │ │ │ │ ├── secure_heap.c │ │ │ │ ├── secure_heap.h │ │ │ │ ├── secure_init.c │ │ │ │ ├── secure_init.h │ │ │ │ └── secure_port_macros.h │ │ │ ├── ARM_CM85_NTZ/ │ │ │ │ └── non_secure/ │ │ │ │ ├── port.c │ │ │ │ ├── portasm.c │ │ │ │ ├── portasm.h │ │ │ │ ├── portmacro.h │ │ │ │ └── portmacrocommon.h │ │ │ ├── ARM_CR5/ │ │ │ │ ├── port.c │ │ │ │ ├── portASM.S │ │ │ │ └── portmacro.h │ │ │ └── ARM_CRx_No_GIC/ │ │ │ ├── port.c │ │ │ ├── portASM.S │ │ │ └── portmacro.h │ │ ├── IAR/ │ │ │ ├── ARM_CA5_No_GIC/ │ │ │ │ ├── port.c │ │ │ │ ├── portASM.h │ │ │ │ ├── portASM.s │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CA9/ │ │ │ │ ├── port.c │ │ │ │ ├── portASM.h │ │ │ │ ├── portASM.s │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CM0/ │ │ │ │ ├── port.c │ │ │ │ ├── portasm.s │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CM23/ │ │ │ │ ├── non_secure/ │ │ │ │ │ ├── port.c │ │ │ │ │ ├── portasm.h │ │ │ │ │ ├── portasm.s │ │ │ │ │ ├── portmacro.h │ │ │ │ │ └── portmacrocommon.h │ │ │ │ └── secure/ │ │ │ │ ├── secure_context.c │ │ │ │ ├── secure_context.h │ │ │ │ ├── secure_context_port_asm.s │ │ │ │ ├── secure_heap.c │ │ │ │ ├── secure_heap.h │ │ │ │ ├── secure_init.c │ │ │ │ ├── secure_init.h │ │ │ │ └── secure_port_macros.h │ │ │ ├── ARM_CM23_NTZ/ │ │ │ │ └── non_secure/ │ │ │ │ ├── port.c │ │ │ │ ├── portasm.h │ │ │ │ ├── portasm.s │ │ │ │ ├── portmacro.h │ │ │ │ └── portmacrocommon.h │ │ │ ├── ARM_CM3/ │ │ │ │ ├── port.c │ │ │ │ ├── portasm.s │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CM33/ │ │ │ │ ├── non_secure/ │ │ │ │ │ ├── port.c │ │ │ │ │ ├── portasm.h │ │ │ │ │ ├── portasm.s │ │ │ │ │ ├── portmacro.h │ │ │ │ │ └── portmacrocommon.h │ │ │ │ └── secure/ │ │ │ │ ├── secure_context.c │ │ │ │ ├── secure_context.h │ │ │ │ ├── secure_context_port_asm.s │ │ │ │ ├── secure_heap.c │ │ │ │ ├── secure_heap.h │ │ │ │ ├── secure_init.c │ │ │ │ ├── secure_init.h │ │ │ │ └── secure_port_macros.h │ │ │ ├── ARM_CM33_NTZ/ │ │ │ │ └── non_secure/ │ │ │ │ ├── port.c │ │ │ │ ├── portasm.h │ │ │ │ ├── portasm.s │ │ │ │ ├── portmacro.h │ │ │ │ └── portmacrocommon.h │ │ │ ├── ARM_CM4F/ │ │ │ │ ├── port.c │ │ │ │ ├── portasm.s │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CM4F_MPU/ │ │ │ │ ├── port.c │ │ │ │ ├── portasm.s │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CM55/ │ │ │ │ ├── non_secure/ │ │ │ │ │ ├── port.c │ │ │ │ │ ├── portasm.h │ │ │ │ │ ├── portasm.s │ │ │ │ │ ├── portmacro.h │ │ │ │ │ └── portmacrocommon.h │ │ │ │ └── secure/ │ │ │ │ ├── secure_context.c │ │ │ │ ├── secure_context.h │ │ │ │ ├── secure_context_port_asm.s │ │ │ │ ├── secure_heap.c │ │ │ │ ├── secure_heap.h │ │ │ │ ├── secure_init.c │ │ │ │ ├── secure_init.h │ │ │ │ └── secure_port_macros.h │ │ │ ├── ARM_CM55_NTZ/ │ │ │ │ └── non_secure/ │ │ │ │ ├── port.c │ │ │ │ ├── portasm.h │ │ │ │ ├── portasm.s │ │ │ │ ├── portmacro.h │ │ │ │ └── portmacrocommon.h │ │ │ ├── ARM_CM7/ │ │ │ │ ├── ReadMe.txt │ │ │ │ └── r0p1/ │ │ │ │ ├── port.c │ │ │ │ ├── portasm.s │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CM85/ │ │ │ │ ├── non_secure/ │ │ │ │ │ ├── port.c │ │ │ │ │ ├── portasm.h │ │ │ │ │ ├── portasm.s │ │ │ │ │ ├── portmacro.h │ │ │ │ │ └── portmacrocommon.h │ │ │ │ └── secure/ │ │ │ │ ├── secure_context.c │ │ │ │ ├── secure_context.h │ │ │ │ ├── secure_context_port_asm.s │ │ │ │ ├── secure_heap.c │ │ │ │ ├── secure_heap.h │ │ │ │ ├── secure_init.c │ │ │ │ ├── secure_init.h │ │ │ │ └── secure_port_macros.h │ │ │ ├── ARM_CM85_NTZ/ │ │ │ │ └── non_secure/ │ │ │ │ ├── port.c │ │ │ │ ├── portasm.h │ │ │ │ ├── portasm.s │ │ │ │ ├── portmacro.h │ │ │ │ └── portmacrocommon.h │ │ │ ├── ARM_CRx_No_GIC/ │ │ │ │ ├── port.c │ │ │ │ ├── portASM.s │ │ │ │ └── portmacro.h │ │ │ ├── LPC2000/ │ │ │ │ ├── ISR_Support.h │ │ │ │ ├── port.c │ │ │ │ ├── portasm.s79 │ │ │ │ └── portmacro.h │ │ │ ├── MSP430/ │ │ │ │ ├── port.c │ │ │ │ ├── portasm.h │ │ │ │ ├── portext.s43 │ │ │ │ └── portmacro.h │ │ │ └── MSP430X/ │ │ │ ├── data_model.h │ │ │ ├── port.c │ │ │ ├── portext.s43 │ │ │ └── portmacro.h │ │ ├── Keil/ │ │ │ └── See-also-the-RVDS-directory.txt │ │ ├── MemMang/ │ │ │ ├── ReadMe.url │ │ │ ├── heap_1.c │ │ │ ├── heap_2.c │ │ │ ├── heap_3.c │ │ │ ├── heap_4.c │ │ │ └── heap_5.c │ │ ├── RVDS/ │ │ │ ├── ARM7_LPC21xx/ │ │ │ │ ├── port.c │ │ │ │ ├── portASM.s │ │ │ │ ├── portmacro.h │ │ │ │ └── portmacro.inc │ │ │ ├── ARM_CA9/ │ │ │ │ ├── port.c │ │ │ │ ├── portASM.s │ │ │ │ ├── portmacro.h │ │ │ │ └── portmacro.inc │ │ │ ├── ARM_CM0/ │ │ │ │ ├── port.c │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CM3/ │ │ │ │ ├── port.c │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CM4F/ │ │ │ │ ├── port.c │ │ │ │ └── portmacro.h │ │ │ ├── ARM_CM4_MPU/ │ │ │ │ ├── port.c │ │ │ │ └── portmacro.h │ │ │ └── ARM_CM7/ │ │ │ ├── ReadMe.txt │ │ │ └── r0p1/ │ │ │ ├── port.c │ │ │ └── portmacro.h │ │ └── readme.txt │ ├── queue.c │ ├── sbom.spdx │ ├── stream_buffer.c │ ├── tasks.c │ ├── timers.c │ └── version_FeeRTOS-202210-LTS.txt ├── LICENSE ├── README.md ├── img/ │ ├── blinky_button.pvs │ ├── blinky_press.sr │ ├── sst0_ek-tm4c.sr │ └── sst_ek-tm4c.sr ├── include/ │ ├── README.txt │ ├── dbc_assert.h │ ├── sst.h │ └── sst.hpp ├── legacy/ │ ├── README.md │ ├── example/ │ │ ├── SST_EXA.PRJ │ │ ├── STDINT.H │ │ ├── bsp.c │ │ ├── bsp.h │ │ ├── kbd_tsk.c │ │ ├── main.c │ │ ├── sst_exa.h │ │ ├── sst_port.h │ │ └── tick_tsk.c │ ├── include/ │ │ └── sst.h │ └── source/ │ └── sst.c ├── sst0_c/ │ ├── README.txt │ ├── examples/ │ │ ├── README.txt │ │ ├── blinky/ │ │ │ ├── armclang/ │ │ │ │ ├── nucleo-l053r8.uvoptx │ │ │ │ └── nucleo-l053r8.uvprojx │ │ │ ├── blinky.c │ │ │ ├── blinky.h │ │ │ ├── bsp.h │ │ │ ├── bsp_nucleo-l053r8.c │ │ │ ├── gnu/ │ │ │ │ └── nucleo-l053r8.mak │ │ │ ├── iar/ │ │ │ │ ├── nucleo-l053r8.ewd │ │ │ │ ├── nucleo-l053r8.ewp │ │ │ │ └── nucleo-l053r8.eww │ │ │ └── main.c │ │ └── blinky_button/ │ │ ├── armclang/ │ │ │ ├── ek-tm4c123gxl.uvoptx │ │ │ ├── ek-tm4c123gxl.uvprojx │ │ │ ├── nucleo-c031c6.uvoptx │ │ │ ├── nucleo-c031c6.uvprojx │ │ │ ├── nucleo-h743zi.uvoptx │ │ │ ├── nucleo-h743zi.uvprojx │ │ │ ├── nucleo-l053r8.uvoptx │ │ │ └── nucleo-l053r8.uvprojx │ │ ├── blinky1.c │ │ ├── blinky3.c │ │ ├── blinky_button.h │ │ ├── bsp.h │ │ ├── bsp_ek-tm4c123gxl.c │ │ ├── bsp_nucleo-c031c6.c │ │ ├── bsp_nucleo-h743zi.c │ │ ├── bsp_nucleo-l053r8.c │ │ ├── button2a.c │ │ ├── button2b.c │ │ ├── gnu/ │ │ │ ├── ek-tm4c123gxl.mak │ │ │ ├── flash_ek-tm4c123gxl.bat │ │ │ ├── nucleo-c031c6.mak │ │ │ ├── nucleo-h743zi.mak │ │ │ └── nucleo-l053r8.mak │ │ ├── iar/ │ │ │ ├── ek-tm4c123gxl.ewd │ │ │ ├── ek-tm4c123gxl.ewp │ │ │ ├── ek-tm4c123gxl.eww │ │ │ ├── nucleo-c031c6.ewd │ │ │ ├── nucleo-c031c6.ewp │ │ │ ├── nucleo-c031c6.eww │ │ │ ├── nucleo-h743zi.ewd │ │ │ ├── nucleo-h743zi.ewp │ │ │ ├── nucleo-h743zi.eww │ │ │ ├── nucleo-l053r8.ewd │ │ │ ├── nucleo-l053r8.ewp │ │ │ └── nucleo-l053r8.eww │ │ └── main.c │ ├── ports/ │ │ └── arm-cm/ │ │ └── sst_port.h │ └── src/ │ └── sst0.c ├── sst0_cpp/ │ ├── README.txt │ ├── examples/ │ │ ├── README.txt │ │ ├── blinky/ │ │ │ ├── armclang/ │ │ │ │ ├── nucleo-l053r8.uvoptx │ │ │ │ └── nucleo-l053r8.uvprojx │ │ │ ├── blinky.cpp │ │ │ ├── blinky.hpp │ │ │ ├── bsp.hpp │ │ │ ├── bsp_nucleo-l053r8.cpp │ │ │ ├── gnu/ │ │ │ │ └── nucleo-l053r8.mak │ │ │ ├── iar/ │ │ │ │ ├── nucleo-l053r8.ewd │ │ │ │ ├── nucleo-l053r8.ewp │ │ │ │ └── nucleo-l053r8.eww │ │ │ └── main.cpp │ │ └── blinky_button/ │ │ ├── armclang/ │ │ │ ├── ek-tm4c123gxl.uvoptx │ │ │ ├── ek-tm4c123gxl.uvprojx │ │ │ ├── nucleo-c031c6.uvoptx │ │ │ ├── nucleo-c031c6.uvprojx │ │ │ ├── nucleo-h743zi.uvoptx │ │ │ ├── nucleo-h743zi.uvprojx │ │ │ ├── nucleo-l053r8.uvoptx │ │ │ └── nucleo-l053r8.uvprojx │ │ ├── blinky1.cpp │ │ ├── blinky3.cpp │ │ ├── blinky_button.hpp │ │ ├── bsp.hpp │ │ ├── bsp_ek-tm4c123gxl.cpp │ │ ├── bsp_nucleo-c031c6.cpp │ │ ├── bsp_nucleo-h743zi.cpp │ │ ├── bsp_nucleo-l053r8.cpp │ │ ├── button2a.cpp │ │ ├── button2b.cpp │ │ ├── gnu/ │ │ │ ├── ek-tm4c123gxl.mak │ │ │ ├── flash_ek-tm4c123gxl.bat │ │ │ ├── nucleo-c031c6.mak │ │ │ ├── nucleo-h743zi.mak │ │ │ └── nucleo-l053r8.mak │ │ ├── iar/ │ │ │ ├── ek-tm4c123gxl.ewd │ │ │ ├── ek-tm4c123gxl.ewp │ │ │ ├── ek-tm4c123gxl.eww │ │ │ ├── nucleo-c031c6.ewd │ │ │ ├── nucleo-c031c6.ewp │ │ │ ├── nucleo-c031c6.eww │ │ │ ├── nucleo-h743zi.ewd │ │ │ ├── nucleo-h743zi.ewp │ │ │ ├── nucleo-h743zi.eww │ │ │ ├── nucleo-l053r8.ewd │ │ │ ├── nucleo-l053r8.ewp │ │ │ └── nucleo-l053r8.eww │ │ └── main.cpp │ ├── ports/ │ │ └── arm-cm/ │ │ └── sst_port.hpp │ └── src/ │ └── sst0.cpp ├── sst_c/ │ ├── README.txt │ ├── examples/ │ │ ├── README.txt │ │ ├── blinky/ │ │ │ ├── armclang/ │ │ │ │ ├── nucleo-l053r8.uvoptx │ │ │ │ └── nucleo-l053r8.uvprojx │ │ │ ├── blinky.c │ │ │ ├── blinky.h │ │ │ ├── bsp.h │ │ │ ├── bsp_nucleo-l053r8.c │ │ │ ├── gnu/ │ │ │ │ └── nucleo-l053r8.mak │ │ │ ├── iar/ │ │ │ │ ├── nucleo-l053r8.ewd │ │ │ │ ├── nucleo-l053r8.ewp │ │ │ │ └── nucleo-l053r8.eww │ │ │ └── main.c │ │ ├── blinky_button/ │ │ │ ├── armclang/ │ │ │ │ ├── ek-tm4c123gxl.uvoptx │ │ │ │ ├── ek-tm4c123gxl.uvprojx │ │ │ │ ├── nucleo-c031c6.uvoptx │ │ │ │ ├── nucleo-c031c6.uvprojx │ │ │ │ ├── nucleo-h743zi.uvoptx │ │ │ │ ├── nucleo-h743zi.uvprojx │ │ │ │ ├── nucleo-l053r8.uvoptx │ │ │ │ └── nucleo-l053r8.uvprojx │ │ │ ├── blinky1.c │ │ │ ├── blinky3.c │ │ │ ├── blinky_button.h │ │ │ ├── bsp.h │ │ │ ├── bsp_ek-tm4c123gxl.c │ │ │ ├── bsp_nucleo-c031c6.c │ │ │ ├── bsp_nucleo-h743zi.c │ │ │ ├── bsp_nucleo-l053r8.c │ │ │ ├── button2a.c │ │ │ ├── button2b.c │ │ │ ├── gnu/ │ │ │ │ ├── ek-tm4c123gxl.mak │ │ │ │ ├── flash_ek-tm4c123gxl.bat │ │ │ │ ├── nucleo-c031c6.mak │ │ │ │ ├── nucleo-h743zi.mak │ │ │ │ └── nucleo-l053r8.mak │ │ │ ├── iar/ │ │ │ │ ├── ek-tm4c123gxl.ewd │ │ │ │ ├── ek-tm4c123gxl.ewp │ │ │ │ ├── ek-tm4c123gxl.eww │ │ │ │ ├── nucleo-c031c6.ewd │ │ │ │ ├── nucleo-c031c6.ewp │ │ │ │ ├── nucleo-c031c6.eww │ │ │ │ ├── nucleo-h743zi.ewd │ │ │ │ ├── nucleo-h743zi.ewp │ │ │ │ ├── nucleo-h743zi.eww │ │ │ │ ├── nucleo-l053r8.ewd │ │ │ │ ├── nucleo-l053r8.ewp │ │ │ │ └── nucleo-l053r8.eww │ │ │ └── main.c │ │ └── blinky_button.X/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── blinky1.c │ │ ├── blinky3.c │ │ ├── blinky_button.h │ │ ├── bsp.h │ │ ├── bsp_dspic33ep128gs804.c │ │ ├── button2a.c │ │ ├── button2b.c │ │ ├── configuration_bits.h │ │ ├── main.c │ │ ├── nbproject/ │ │ │ ├── configurations.xml │ │ │ └── project.xml │ │ ├── system_dspic33ep128gs804.c │ │ └── system_dspic33ep128gs804.h │ ├── ports/ │ │ ├── arm-cm/ │ │ │ ├── sst_port.c │ │ │ └── sst_port.h │ │ └── dspic/ │ │ ├── sst_port.c │ │ └── sst_port.h │ └── src/ │ └── sst.c └── sst_cpp/ ├── README.txt ├── examples/ │ ├── README.txt │ ├── blinky/ │ │ ├── armclang/ │ │ │ ├── nucleo-l053r8.uvoptx │ │ │ └── nucleo-l053r8.uvprojx │ │ ├── blinky.cpp │ │ ├── blinky.hpp │ │ ├── bsp.hpp │ │ ├── bsp_nucleo-l053r8.cpp │ │ ├── gnu/ │ │ │ └── nucleo-l053r8.mak │ │ ├── iar/ │ │ │ ├── nucleo-l053r8.ewd │ │ │ ├── nucleo-l053r8.ewp │ │ │ └── nucleo-l053r8.eww │ │ └── main.cpp │ └── blinky_button/ │ ├── armclang/ │ │ ├── ek-tm4c123gxl.uvoptx │ │ ├── ek-tm4c123gxl.uvprojx │ │ ├── nucleo-c031c6.uvoptx │ │ ├── nucleo-c031c6.uvprojx │ │ ├── nucleo-h743zi.uvoptx │ │ ├── nucleo-h743zi.uvprojx │ │ ├── nucleo-l053r8.uvoptx │ │ └── nucleo-l053r8.uvprojx │ ├── blinky1.cpp │ ├── blinky3.cpp │ ├── blinky_button.hpp │ ├── bsp.hpp │ ├── bsp_ek-tm4c123gxl.cpp │ ├── bsp_nucleo-c031c6.cpp │ ├── bsp_nucleo-h743zi.cpp │ ├── bsp_nucleo-l053r8.cpp │ ├── button2a.cpp │ ├── button2b.cpp │ ├── gnu/ │ │ ├── ek-tm4c123gxl.mak │ │ ├── flash_ek-tm4c123gxl.bat │ │ ├── nucleo-c031c6.mak │ │ ├── nucleo-h743zi.mak │ │ └── nucleo-l053r8.mak │ ├── iar/ │ │ ├── ek-tm4c123gxl.ewd │ │ ├── ek-tm4c123gxl.ewp │ │ ├── ek-tm4c123gxl.eww │ │ ├── nucleo-c031c6.ewd │ │ ├── nucleo-c031c6.ewp │ │ ├── nucleo-c031c6.eww │ │ ├── nucleo-h743zi.ewd │ │ ├── nucleo-h743zi.ewp │ │ ├── nucleo-h743zi.eww │ │ ├── nucleo-l053r8.ewd │ │ ├── nucleo-l053r8.ewp │ │ └── nucleo-l053r8.eww │ └── main.cpp ├── ports/ │ └── arm-cm/ │ ├── sst_port.cpp │ └── sst_port.hpp └── src/ └── sst.cpp ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # build directories build*/ bin*/ # test directories test_priv/ ================================================ FILE: .vscode/settings.json ================================================ { "files.associations": { "system_dspic33ep128gs804.h": "c" } } ================================================ FILE: 3rd_party/CMSIS/Include/cmsis_armcc.h ================================================ /**************************************************************************//** * @file cmsis_armcc.h * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file * @version V5.1.0 * @date 08. May 2019 ******************************************************************************/ /* * Copyright (c) 2009-2019 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef __CMSIS_ARMCC_H #define __CMSIS_ARMCC_H #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) #error "Please use Arm Compiler Toolchain V4.0.677 or later!" #endif /* CMSIS compiler control architecture macros */ #if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) #define __ARM_ARCH_6M__ 1 #endif #if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) #define __ARM_ARCH_7M__ 1 #endif #if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) #define __ARM_ARCH_7EM__ 1 #endif /* __ARM_ARCH_8M_BASE__ not applicable */ /* __ARM_ARCH_8M_MAIN__ not applicable */ /* CMSIS compiler control DSP macros */ #if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) #define __ARM_FEATURE_DSP 1 #endif /* CMSIS compiler specific defines */ #ifndef __ASM #define __ASM __asm #endif #ifndef __INLINE #define __INLINE __inline #endif #ifndef __STATIC_INLINE #define __STATIC_INLINE static __inline #endif #ifndef __STATIC_FORCEINLINE #define __STATIC_FORCEINLINE static __forceinline #endif #ifndef __NO_RETURN #define __NO_RETURN __declspec(noreturn) #endif #ifndef __USED #define __USED __attribute__((used)) #endif #ifndef __WEAK #define __WEAK __attribute__((weak)) #endif #ifndef __PACKED #define __PACKED __attribute__((packed)) #endif #ifndef __PACKED_STRUCT #define __PACKED_STRUCT __packed struct #endif #ifndef __PACKED_UNION #define __PACKED_UNION __packed union #endif #ifndef __UNALIGNED_UINT32 /* deprecated */ #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) #endif #ifndef __UNALIGNED_UINT16_WRITE #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) #endif #ifndef __UNALIGNED_UINT16_READ #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) #endif #ifndef __UNALIGNED_UINT32_WRITE #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) #endif #ifndef __UNALIGNED_UINT32_READ #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) #endif #ifndef __ALIGNED #define __ALIGNED(x) __attribute__((aligned(x))) #endif #ifndef __RESTRICT #define __RESTRICT __restrict #endif #ifndef __COMPILER_BARRIER #define __COMPILER_BARRIER() __memory_changed() #endif /* ######################### Startup and Lowlevel Init ######################## */ #ifndef __PROGRAM_START #define __PROGRAM_START __main #endif #ifndef __INITIAL_SP #define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit #endif #ifndef __STACK_LIMIT #define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base #endif #ifndef __VECTOR_TABLE #define __VECTOR_TABLE __Vectors #endif #ifndef __VECTOR_TABLE_ATTRIBUTE #define __VECTOR_TABLE_ATTRIBUTE __attribute((used, section("RESET"))) #endif /* ########################### Core Function Access ########################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions @{ */ /** \brief Enable IRQ Interrupts \details Enables IRQ interrupts by clearing the I-bit in the CPSR. Can only be executed in Privileged modes. */ /* intrinsic void __enable_irq(); */ /** \brief Disable IRQ Interrupts \details Disables IRQ interrupts by setting the I-bit in the CPSR. Can only be executed in Privileged modes. */ /* intrinsic void __disable_irq(); */ /** \brief Get Control Register \details Returns the content of the Control Register. \return Control Register value */ __STATIC_INLINE uint32_t __get_CONTROL(void) { register uint32_t __regControl __ASM("control"); return(__regControl); } /** \brief Set Control Register \details Writes the given value to the Control Register. \param [in] control Control Register value to set */ __STATIC_INLINE void __set_CONTROL(uint32_t control) { register uint32_t __regControl __ASM("control"); __regControl = control; } /** \brief Get IPSR Register \details Returns the content of the IPSR Register. \return IPSR Register value */ __STATIC_INLINE uint32_t __get_IPSR(void) { register uint32_t __regIPSR __ASM("ipsr"); return(__regIPSR); } /** \brief Get APSR Register \details Returns the content of the APSR Register. \return APSR Register value */ __STATIC_INLINE uint32_t __get_APSR(void) { register uint32_t __regAPSR __ASM("apsr"); return(__regAPSR); } /** \brief Get xPSR Register \details Returns the content of the xPSR Register. \return xPSR Register value */ __STATIC_INLINE uint32_t __get_xPSR(void) { register uint32_t __regXPSR __ASM("xpsr"); return(__regXPSR); } /** \brief Get Process Stack Pointer \details Returns the current value of the Process Stack Pointer (PSP). \return PSP Register value */ __STATIC_INLINE uint32_t __get_PSP(void) { register uint32_t __regProcessStackPointer __ASM("psp"); return(__regProcessStackPointer); } /** \brief Set Process Stack Pointer \details Assigns the given value to the Process Stack Pointer (PSP). \param [in] topOfProcStack Process Stack Pointer value to set */ __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) { register uint32_t __regProcessStackPointer __ASM("psp"); __regProcessStackPointer = topOfProcStack; } /** \brief Get Main Stack Pointer \details Returns the current value of the Main Stack Pointer (MSP). \return MSP Register value */ __STATIC_INLINE uint32_t __get_MSP(void) { register uint32_t __regMainStackPointer __ASM("msp"); return(__regMainStackPointer); } /** \brief Set Main Stack Pointer \details Assigns the given value to the Main Stack Pointer (MSP). \param [in] topOfMainStack Main Stack Pointer value to set */ __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) { register uint32_t __regMainStackPointer __ASM("msp"); __regMainStackPointer = topOfMainStack; } /** \brief Get Priority Mask \details Returns the current state of the priority mask bit from the Priority Mask Register. \return Priority Mask value */ __STATIC_INLINE uint32_t __get_PRIMASK(void) { register uint32_t __regPriMask __ASM("primask"); return(__regPriMask); } /** \brief Set Priority Mask \details Assigns the given value to the Priority Mask Register. \param [in] priMask Priority Mask */ __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) { register uint32_t __regPriMask __ASM("primask"); __regPriMask = (priMask); } #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) /** \brief Enable FIQ \details Enables FIQ interrupts by clearing the F-bit in the CPSR. Can only be executed in Privileged modes. */ #define __enable_fault_irq __enable_fiq /** \brief Disable FIQ \details Disables FIQ interrupts by setting the F-bit in the CPSR. Can only be executed in Privileged modes. */ #define __disable_fault_irq __disable_fiq /** \brief Get Base Priority \details Returns the current value of the Base Priority register. \return Base Priority register value */ __STATIC_INLINE uint32_t __get_BASEPRI(void) { register uint32_t __regBasePri __ASM("basepri"); return(__regBasePri); } /** \brief Set Base Priority \details Assigns the given value to the Base Priority register. \param [in] basePri Base Priority value to set */ __STATIC_INLINE void __set_BASEPRI(uint32_t basePri) { register uint32_t __regBasePri __ASM("basepri"); __regBasePri = (basePri & 0xFFU); } /** \brief Set Base Priority with condition \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, or the new value increases the BASEPRI priority level. \param [in] basePri Base Priority value to set */ __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) { register uint32_t __regBasePriMax __ASM("basepri_max"); __regBasePriMax = (basePri & 0xFFU); } /** \brief Get Fault Mask \details Returns the current value of the Fault Mask register. \return Fault Mask register value */ __STATIC_INLINE uint32_t __get_FAULTMASK(void) { register uint32_t __regFaultMask __ASM("faultmask"); return(__regFaultMask); } /** \brief Set Fault Mask \details Assigns the given value to the Fault Mask register. \param [in] faultMask Fault Mask value to set */ __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) { register uint32_t __regFaultMask __ASM("faultmask"); __regFaultMask = (faultMask & (uint32_t)1U); } #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ /** \brief Get FPSCR \details Returns the current value of the Floating Point Status/Control register. \return Floating Point Status/Control register value */ __STATIC_INLINE uint32_t __get_FPSCR(void) { #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) register uint32_t __regfpscr __ASM("fpscr"); return(__regfpscr); #else return(0U); #endif } /** \brief Set FPSCR \details Assigns the given value to the Floating Point Status/Control register. \param [in] fpscr Floating Point Status/Control value to set */ __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) { #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) register uint32_t __regfpscr __ASM("fpscr"); __regfpscr = (fpscr); #else (void)fpscr; #endif } /*@} end of CMSIS_Core_RegAccFunctions */ /* ########################## Core Instruction Access ######################### */ /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface Access to dedicated instructions @{ */ /** \brief No Operation \details No Operation does nothing. This instruction can be used for code alignment purposes. */ #define __NOP __nop /** \brief Wait For Interrupt \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. */ #define __WFI __wfi /** \brief Wait For Event \details Wait For Event is a hint instruction that permits the processor to enter a low-power state until one of a number of events occurs. */ #define __WFE __wfe /** \brief Send Event \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. */ #define __SEV __sev /** \brief Instruction Synchronization Barrier \details Instruction Synchronization Barrier flushes the pipeline in the processor, so that all instructions following the ISB are fetched from cache or memory, after the instruction has been completed. */ #define __ISB() do {\ __schedule_barrier();\ __isb(0xF);\ __schedule_barrier();\ } while (0U) /** \brief Data Synchronization Barrier \details Acts as a special kind of Data Memory Barrier. It completes when all explicit memory accesses before this instruction complete. */ #define __DSB() do {\ __schedule_barrier();\ __dsb(0xF);\ __schedule_barrier();\ } while (0U) /** \brief Data Memory Barrier \details Ensures the apparent order of the explicit memory operations before and after the instruction, without ensuring their completion. */ #define __DMB() do {\ __schedule_barrier();\ __dmb(0xF);\ __schedule_barrier();\ } while (0U) /** \brief Reverse byte order (32 bit) \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. \param [in] value Value to reverse \return Reversed value */ #define __REV __rev /** \brief Reverse byte order (16 bit) \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. \param [in] value Value to reverse \return Reversed value */ #ifndef __NO_EMBEDDED_ASM __attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) { rev16 r0, r0 bx lr } #endif /** \brief Reverse byte order (16 bit) \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. \param [in] value Value to reverse \return Reversed value */ #ifndef __NO_EMBEDDED_ASM __attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) { revsh r0, r0 bx lr } #endif /** \brief Rotate Right in unsigned value (32 bit) \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. \param [in] op1 Value to rotate \param [in] op2 Number of Bits to rotate \return Rotated value */ #define __ROR __ror /** \brief Breakpoint \details Causes the processor to enter Debug state. Debug tools can use this to investigate system state when the instruction at a particular address is reached. \param [in] value is ignored by the processor. If required, a debugger can use it to store additional information about the breakpoint. */ #define __BKPT(value) __breakpoint(value) /** \brief Reverse bit order of value \details Reverses the bit order of the given value. \param [in] value Value to reverse \return Reversed value */ #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) #define __RBIT __rbit #else __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) { uint32_t result; uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ result = value; /* r will be reversed bits of v; first get LSB of v */ for (value >>= 1U; value != 0U; value >>= 1U) { result <<= 1U; result |= value & 1U; s--; } result <<= s; /* shift when v's highest bits are zero */ return result; } #endif /** \brief Count leading zeros \details Counts the number of leading zeros of a data value. \param [in] value Value to count the leading zeros \return number of leading zeros in value */ #define __CLZ __clz #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) /** \brief LDR Exclusive (8 bit) \details Executes a exclusive LDR instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) #else #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") #endif /** \brief LDR Exclusive (16 bit) \details Executes a exclusive LDR instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) #else #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") #endif /** \brief LDR Exclusive (32 bit) \details Executes a exclusive LDR instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) #else #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") #endif /** \brief STR Exclusive (8 bit) \details Executes a exclusive STR instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) #define __STREXB(value, ptr) __strex(value, ptr) #else #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") #endif /** \brief STR Exclusive (16 bit) \details Executes a exclusive STR instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) #define __STREXH(value, ptr) __strex(value, ptr) #else #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") #endif /** \brief STR Exclusive (32 bit) \details Executes a exclusive STR instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) #define __STREXW(value, ptr) __strex(value, ptr) #else #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") #endif /** \brief Remove the exclusive lock \details Removes the exclusive lock which is created by LDREX. */ #define __CLREX __clrex /** \brief Signed Saturate \details Saturates a signed value. \param [in] value Value to be saturated \param [in] sat Bit position to saturate to (1..32) \return Saturated value */ #define __SSAT __ssat /** \brief Unsigned Saturate \details Saturates an unsigned value. \param [in] value Value to be saturated \param [in] sat Bit position to saturate to (0..31) \return Saturated value */ #define __USAT __usat /** \brief Rotate Right with Extend (32 bit) \details Moves each bit of a bitstring right by one bit. The carry input is shifted in at the left end of the bitstring. \param [in] value Value to rotate \return Rotated value */ #ifndef __NO_EMBEDDED_ASM __attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) { rrx r0, r0 bx lr } #endif /** \brief LDRT Unprivileged (8 bit) \details Executes a Unprivileged LDRT instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ #define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) /** \brief LDRT Unprivileged (16 bit) \details Executes a Unprivileged LDRT instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ #define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) /** \brief LDRT Unprivileged (32 bit) \details Executes a Unprivileged LDRT instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ #define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) /** \brief STRT Unprivileged (8 bit) \details Executes a Unprivileged STRT instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ #define __STRBT(value, ptr) __strt(value, ptr) /** \brief STRT Unprivileged (16 bit) \details Executes a Unprivileged STRT instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ #define __STRHT(value, ptr) __strt(value, ptr) /** \brief STRT Unprivileged (32 bit) \details Executes a Unprivileged STRT instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ #define __STRT(value, ptr) __strt(value, ptr) #else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ /** \brief Signed Saturate \details Saturates a signed value. \param [in] value Value to be saturated \param [in] sat Bit position to saturate to (1..32) \return Saturated value */ __attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) { if ((sat >= 1U) && (sat <= 32U)) { const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); const int32_t min = -1 - max ; if (val > max) { return max; } else if (val < min) { return min; } } return val; } /** \brief Unsigned Saturate \details Saturates an unsigned value. \param [in] value Value to be saturated \param [in] sat Bit position to saturate to (0..31) \return Saturated value */ __attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) { if (sat <= 31U) { const uint32_t max = ((1U << sat) - 1U); if (val > (int32_t)max) { return max; } else if (val < 0) { return 0U; } } return (uint32_t)val; } #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ /*@}*/ /* end of group CMSIS_Core_InstructionInterface */ /* ################### Compiler specific Intrinsics ########################### */ /** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics Access to dedicated SIMD instructions @{ */ #if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) #define __SADD8 __sadd8 #define __QADD8 __qadd8 #define __SHADD8 __shadd8 #define __UADD8 __uadd8 #define __UQADD8 __uqadd8 #define __UHADD8 __uhadd8 #define __SSUB8 __ssub8 #define __QSUB8 __qsub8 #define __SHSUB8 __shsub8 #define __USUB8 __usub8 #define __UQSUB8 __uqsub8 #define __UHSUB8 __uhsub8 #define __SADD16 __sadd16 #define __QADD16 __qadd16 #define __SHADD16 __shadd16 #define __UADD16 __uadd16 #define __UQADD16 __uqadd16 #define __UHADD16 __uhadd16 #define __SSUB16 __ssub16 #define __QSUB16 __qsub16 #define __SHSUB16 __shsub16 #define __USUB16 __usub16 #define __UQSUB16 __uqsub16 #define __UHSUB16 __uhsub16 #define __SASX __sasx #define __QASX __qasx #define __SHASX __shasx #define __UASX __uasx #define __UQASX __uqasx #define __UHASX __uhasx #define __SSAX __ssax #define __QSAX __qsax #define __SHSAX __shsax #define __USAX __usax #define __UQSAX __uqsax #define __UHSAX __uhsax #define __USAD8 __usad8 #define __USADA8 __usada8 #define __SSAT16 __ssat16 #define __USAT16 __usat16 #define __UXTB16 __uxtb16 #define __UXTAB16 __uxtab16 #define __SXTB16 __sxtb16 #define __SXTAB16 __sxtab16 #define __SMUAD __smuad #define __SMUADX __smuadx #define __SMLAD __smlad #define __SMLADX __smladx #define __SMLALD __smlald #define __SMLALDX __smlaldx #define __SMUSD __smusd #define __SMUSDX __smusdx #define __SMLSD __smlsd #define __SMLSDX __smlsdx #define __SMLSLD __smlsld #define __SMLSLDX __smlsldx #define __SEL __sel #define __QADD __qadd #define __QSUB __qsub #define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) #define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) #define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ ((int64_t)(ARG3) << 32U) ) >> 32U)) #endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ /*@} end of group CMSIS_SIMD_intrinsics */ #endif /* __CMSIS_ARMCC_H */ ================================================ FILE: 3rd_party/CMSIS/Include/cmsis_armclang.h ================================================ /**************************************************************************//** * @file cmsis_armclang.h * @brief CMSIS compiler armclang (Arm Compiler 6) header file * @version V5.2.0 * @date 08. May 2019 ******************************************************************************/ /* * Copyright (c) 2009-2019 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ #ifndef __CMSIS_ARMCLANG_H #define __CMSIS_ARMCLANG_H #pragma clang system_header /* treat file as system include file */ #ifndef __ARM_COMPAT_H #include /* Compatibility header for Arm Compiler 5 intrinsics */ #endif /* CMSIS compiler specific defines */ #ifndef __ASM #define __ASM __asm #endif #ifndef __INLINE #define __INLINE __inline #endif #ifndef __STATIC_INLINE #define __STATIC_INLINE static __inline #endif #ifndef __STATIC_FORCEINLINE #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline #endif #ifndef __NO_RETURN #define __NO_RETURN __attribute__((__noreturn__)) #endif #ifndef __USED #define __USED __attribute__((used)) #endif #ifndef __WEAK #define __WEAK __attribute__((weak)) #endif #ifndef __PACKED #define __PACKED __attribute__((packed, aligned(1))) #endif #ifndef __PACKED_STRUCT #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) #endif #ifndef __PACKED_UNION #define __PACKED_UNION union __attribute__((packed, aligned(1))) #endif #ifndef __UNALIGNED_UINT32 /* deprecated */ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpacked" /*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ struct __attribute__((packed)) T_UINT32 { uint32_t v; }; #pragma clang diagnostic pop #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) #endif #ifndef __UNALIGNED_UINT16_WRITE #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpacked" /*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; #pragma clang diagnostic pop #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT16_READ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpacked" /*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; #pragma clang diagnostic pop #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) #endif #ifndef __UNALIGNED_UINT32_WRITE #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpacked" /*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; #pragma clang diagnostic pop #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT32_READ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpacked" /*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; #pragma clang diagnostic pop #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) #endif #ifndef __ALIGNED #define __ALIGNED(x) __attribute__((aligned(x))) #endif #ifndef __RESTRICT #define __RESTRICT __restrict #endif #ifndef __COMPILER_BARRIER #define __COMPILER_BARRIER() __ASM volatile("":::"memory") #endif /* ######################### Startup and Lowlevel Init ######################## */ #ifndef __PROGRAM_START #define __PROGRAM_START __main #endif #ifndef __INITIAL_SP #define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit #endif #ifndef __STACK_LIMIT #define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base #endif #ifndef __VECTOR_TABLE #define __VECTOR_TABLE __Vectors #endif #ifndef __VECTOR_TABLE_ATTRIBUTE #define __VECTOR_TABLE_ATTRIBUTE __attribute((used, section("RESET"))) #endif /* ########################### Core Function Access ########################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions @{ */ /** \brief Enable IRQ Interrupts \details Enables IRQ interrupts by clearing the I-bit in the CPSR. Can only be executed in Privileged modes. */ /* intrinsic void __enable_irq(); see arm_compat.h */ /** \brief Disable IRQ Interrupts \details Disables IRQ interrupts by setting the I-bit in the CPSR. Can only be executed in Privileged modes. */ /* intrinsic void __disable_irq(); see arm_compat.h */ /** \brief Get Control Register \details Returns the content of the Control Register. \return Control Register value */ __STATIC_FORCEINLINE uint32_t __get_CONTROL(void) { uint32_t result; __ASM volatile ("MRS %0, control" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Control Register (non-secure) \details Returns the content of the non-secure Control Register when in secure mode. \return non-secure Control Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) { uint32_t result; __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Control Register \details Writes the given value to the Control Register. \param [in] control Control Register value to set */ __STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) { __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Control Register (non-secure) \details Writes the given value to the non-secure Control Register when in secure state. \param [in] control Control Register value to set */ __STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) { __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); } #endif /** \brief Get IPSR Register \details Returns the content of the IPSR Register. \return IPSR Register value */ __STATIC_FORCEINLINE uint32_t __get_IPSR(void) { uint32_t result; __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); return(result); } /** \brief Get APSR Register \details Returns the content of the APSR Register. \return APSR Register value */ __STATIC_FORCEINLINE uint32_t __get_APSR(void) { uint32_t result; __ASM volatile ("MRS %0, apsr" : "=r" (result) ); return(result); } /** \brief Get xPSR Register \details Returns the content of the xPSR Register. \return xPSR Register value */ __STATIC_FORCEINLINE uint32_t __get_xPSR(void) { uint32_t result; __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); return(result); } /** \brief Get Process Stack Pointer \details Returns the current value of the Process Stack Pointer (PSP). \return PSP Register value */ __STATIC_FORCEINLINE uint32_t __get_PSP(void) { uint32_t result; __ASM volatile ("MRS %0, psp" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Process Stack Pointer (non-secure) \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. \return PSP Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) { uint32_t result; __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Process Stack Pointer \details Assigns the given value to the Process Stack Pointer (PSP). \param [in] topOfProcStack Process Stack Pointer value to set */ __STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) { __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Process Stack Pointer (non-secure) \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. \param [in] topOfProcStack Process Stack Pointer value to set */ __STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) { __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); } #endif /** \brief Get Main Stack Pointer \details Returns the current value of the Main Stack Pointer (MSP). \return MSP Register value */ __STATIC_FORCEINLINE uint32_t __get_MSP(void) { uint32_t result; __ASM volatile ("MRS %0, msp" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Main Stack Pointer (non-secure) \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. \return MSP Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) { uint32_t result; __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Main Stack Pointer \details Assigns the given value to the Main Stack Pointer (MSP). \param [in] topOfMainStack Main Stack Pointer value to set */ __STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) { __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Main Stack Pointer (non-secure) \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. \param [in] topOfMainStack Main Stack Pointer value to set */ __STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) { __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); } #endif #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Stack Pointer (non-secure) \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. \return SP Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) { uint32_t result; __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); return(result); } /** \brief Set Stack Pointer (non-secure) \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. \param [in] topOfStack Stack Pointer value to set */ __STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) { __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); } #endif /** \brief Get Priority Mask \details Returns the current state of the priority mask bit from the Priority Mask Register. \return Priority Mask value */ __STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) { uint32_t result; __ASM volatile ("MRS %0, primask" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Priority Mask (non-secure) \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. \return Priority Mask value */ __STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) { uint32_t result; __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Priority Mask \details Assigns the given value to the Priority Mask Register. \param [in] priMask Priority Mask */ __STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) { __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Priority Mask (non-secure) \details Assigns the given value to the non-secure Priority Mask Register when in secure state. \param [in] priMask Priority Mask */ __STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) { __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); } #endif #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) /** \brief Enable FIQ \details Enables FIQ interrupts by clearing the F-bit in the CPSR. Can only be executed in Privileged modes. */ #define __enable_fault_irq __enable_fiq /* see arm_compat.h */ /** \brief Disable FIQ \details Disables FIQ interrupts by setting the F-bit in the CPSR. Can only be executed in Privileged modes. */ #define __disable_fault_irq __disable_fiq /* see arm_compat.h */ /** \brief Get Base Priority \details Returns the current value of the Base Priority register. \return Base Priority register value */ __STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) { uint32_t result; __ASM volatile ("MRS %0, basepri" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Base Priority (non-secure) \details Returns the current value of the non-secure Base Priority register when in secure state. \return Base Priority register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) { uint32_t result; __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Base Priority \details Assigns the given value to the Base Priority register. \param [in] basePri Base Priority value to set */ __STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) { __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Base Priority (non-secure) \details Assigns the given value to the non-secure Base Priority register when in secure state. \param [in] basePri Base Priority value to set */ __STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) { __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); } #endif /** \brief Set Base Priority with condition \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, or the new value increases the BASEPRI priority level. \param [in] basePri Base Priority value to set */ __STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) { __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); } /** \brief Get Fault Mask \details Returns the current value of the Fault Mask register. \return Fault Mask register value */ __STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) { uint32_t result; __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Fault Mask (non-secure) \details Returns the current value of the non-secure Fault Mask register when in secure state. \return Fault Mask register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) { uint32_t result; __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Fault Mask \details Assigns the given value to the Fault Mask register. \param [in] faultMask Fault Mask value to set */ __STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) { __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Fault Mask (non-secure) \details Assigns the given value to the non-secure Fault Mask register when in secure state. \param [in] faultMask Fault Mask value to set */ __STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) { __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); } #endif #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) /** \brief Get Process Stack Pointer Limit Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence zero is returned always in non-secure mode. \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). \return PSPLIM Register value */ __STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure PSPLIM is RAZ/WI return 0U; #else uint32_t result; __ASM volatile ("MRS %0, psplim" : "=r" (result) ); return result; #endif } #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Process Stack Pointer Limit (non-secure) Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence zero is returned always in non-secure mode. \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. \return PSPLIM Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) // without main extensions, the non-secure PSPLIM is RAZ/WI return 0U; #else uint32_t result; __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); return result; #endif } #endif /** \brief Set Process Stack Pointer Limit Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence the write is silently ignored in non-secure mode. \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set */ __STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure PSPLIM is RAZ/WI (void)ProcStackPtrLimit; #else __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); #endif } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Process Stack Pointer (non-secure) Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence the write is silently ignored in non-secure mode. \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set */ __STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) // without main extensions, the non-secure PSPLIM is RAZ/WI (void)ProcStackPtrLimit; #else __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); #endif } #endif /** \brief Get Main Stack Pointer Limit Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence zero is returned always. \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). \return MSPLIM Register value */ __STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure MSPLIM is RAZ/WI return 0U; #else uint32_t result; __ASM volatile ("MRS %0, msplim" : "=r" (result) ); return result; #endif } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Main Stack Pointer Limit (non-secure) Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence zero is returned always. \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. \return MSPLIM Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) // without main extensions, the non-secure MSPLIM is RAZ/WI return 0U; #else uint32_t result; __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); return result; #endif } #endif /** \brief Set Main Stack Pointer Limit Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence the write is silently ignored. \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set */ __STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure MSPLIM is RAZ/WI (void)MainStackPtrLimit; #else __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); #endif } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Main Stack Pointer Limit (non-secure) Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence the write is silently ignored. \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. \param [in] MainStackPtrLimit Main Stack Pointer value to set */ __STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) // without main extensions, the non-secure MSPLIM is RAZ/WI (void)MainStackPtrLimit; #else __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); #endif } #endif #endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ /** \brief Get FPSCR \details Returns the current value of the Floating Point Status/Control register. \return Floating Point Status/Control register value */ #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) #define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr #else #define __get_FPSCR() ((uint32_t)0U) #endif /** \brief Set FPSCR \details Assigns the given value to the Floating Point Status/Control register. \param [in] fpscr Floating Point Status/Control value to set */ #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) #define __set_FPSCR __builtin_arm_set_fpscr #else #define __set_FPSCR(x) ((void)(x)) #endif /*@} end of CMSIS_Core_RegAccFunctions */ /* ########################## Core Instruction Access ######################### */ /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface Access to dedicated instructions @{ */ /* Define macros for porting to both thumb1 and thumb2. * For thumb1, use low register (r0-r7), specified by constraint "l" * Otherwise, use general registers, specified by constraint "r" */ #if defined (__thumb__) && !defined (__thumb2__) #define __CMSIS_GCC_OUT_REG(r) "=l" (r) #define __CMSIS_GCC_RW_REG(r) "+l" (r) #define __CMSIS_GCC_USE_REG(r) "l" (r) #else #define __CMSIS_GCC_OUT_REG(r) "=r" (r) #define __CMSIS_GCC_RW_REG(r) "+r" (r) #define __CMSIS_GCC_USE_REG(r) "r" (r) #endif /** \brief No Operation \details No Operation does nothing. This instruction can be used for code alignment purposes. */ #define __NOP __builtin_arm_nop /** \brief Wait For Interrupt \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. */ #define __WFI __builtin_arm_wfi /** \brief Wait For Event \details Wait For Event is a hint instruction that permits the processor to enter a low-power state until one of a number of events occurs. */ #define __WFE __builtin_arm_wfe /** \brief Send Event \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. */ #define __SEV __builtin_arm_sev /** \brief Instruction Synchronization Barrier \details Instruction Synchronization Barrier flushes the pipeline in the processor, so that all instructions following the ISB are fetched from cache or memory, after the instruction has been completed. */ #define __ISB() __builtin_arm_isb(0xF) /** \brief Data Synchronization Barrier \details Acts as a special kind of Data Memory Barrier. It completes when all explicit memory accesses before this instruction complete. */ #define __DSB() __builtin_arm_dsb(0xF) /** \brief Data Memory Barrier \details Ensures the apparent order of the explicit memory operations before and after the instruction, without ensuring their completion. */ #define __DMB() __builtin_arm_dmb(0xF) /** \brief Reverse byte order (32 bit) \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. \param [in] value Value to reverse \return Reversed value */ #define __REV(value) __builtin_bswap32(value) /** \brief Reverse byte order (16 bit) \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. \param [in] value Value to reverse \return Reversed value */ #define __REV16(value) __ROR(__REV(value), 16) /** \brief Reverse byte order (16 bit) \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. \param [in] value Value to reverse \return Reversed value */ #define __REVSH(value) (int16_t)__builtin_bswap16(value) /** \brief Rotate Right in unsigned value (32 bit) \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. \param [in] op1 Value to rotate \param [in] op2 Number of Bits to rotate \return Rotated value */ __STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) { op2 %= 32U; if (op2 == 0U) { return op1; } return (op1 >> op2) | (op1 << (32U - op2)); } /** \brief Breakpoint \details Causes the processor to enter Debug state. Debug tools can use this to investigate system state when the instruction at a particular address is reached. \param [in] value is ignored by the processor. If required, a debugger can use it to store additional information about the breakpoint. */ #define __BKPT(value) __ASM volatile ("bkpt "#value) /** \brief Reverse bit order of value \details Reverses the bit order of the given value. \param [in] value Value to reverse \return Reversed value */ #define __RBIT __builtin_arm_rbit /** \brief Count leading zeros \details Counts the number of leading zeros of a data value. \param [in] value Value to count the leading zeros \return number of leading zeros in value */ __STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) { /* Even though __builtin_clz produces a CLZ instruction on ARM, formally __builtin_clz(0) is undefined behaviour, so handle this case specially. This guarantees ARM-compatible results if happening to compile on a non-ARM target, and ensures the compiler doesn't decide to activate any optimisations using the logic "value was passed to __builtin_clz, so it is non-zero". ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a single CLZ instruction. */ if (value == 0U) { return 32U; } return __builtin_clz(value); } #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) /** \brief LDR Exclusive (8 bit) \details Executes a exclusive LDR instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ #define __LDREXB (uint8_t)__builtin_arm_ldrex /** \brief LDR Exclusive (16 bit) \details Executes a exclusive LDR instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ #define __LDREXH (uint16_t)__builtin_arm_ldrex /** \brief LDR Exclusive (32 bit) \details Executes a exclusive LDR instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ #define __LDREXW (uint32_t)__builtin_arm_ldrex /** \brief STR Exclusive (8 bit) \details Executes a exclusive STR instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ #define __STREXB (uint32_t)__builtin_arm_strex /** \brief STR Exclusive (16 bit) \details Executes a exclusive STR instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ #define __STREXH (uint32_t)__builtin_arm_strex /** \brief STR Exclusive (32 bit) \details Executes a exclusive STR instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ #define __STREXW (uint32_t)__builtin_arm_strex /** \brief Remove the exclusive lock \details Removes the exclusive lock which is created by LDREX. */ #define __CLREX __builtin_arm_clrex #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) /** \brief Signed Saturate \details Saturates a signed value. \param [in] value Value to be saturated \param [in] sat Bit position to saturate to (1..32) \return Saturated value */ #define __SSAT __builtin_arm_ssat /** \brief Unsigned Saturate \details Saturates an unsigned value. \param [in] value Value to be saturated \param [in] sat Bit position to saturate to (0..31) \return Saturated value */ #define __USAT __builtin_arm_usat /** \brief Rotate Right with Extend (32 bit) \details Moves each bit of a bitstring right by one bit. The carry input is shifted in at the left end of the bitstring. \param [in] value Value to rotate \return Rotated value */ __STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) { uint32_t result; __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); return(result); } /** \brief LDRT Unprivileged (8 bit) \details Executes a Unprivileged LDRT instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ __STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) { uint32_t result; __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); return ((uint8_t) result); /* Add explicit type cast here */ } /** \brief LDRT Unprivileged (16 bit) \details Executes a Unprivileged LDRT instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ __STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) { uint32_t result; __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); return ((uint16_t) result); /* Add explicit type cast here */ } /** \brief LDRT Unprivileged (32 bit) \details Executes a Unprivileged LDRT instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ __STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) { uint32_t result; __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); return(result); } /** \brief STRT Unprivileged (8 bit) \details Executes a Unprivileged STRT instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) { __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief STRT Unprivileged (16 bit) \details Executes a Unprivileged STRT instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) { __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief STRT Unprivileged (32 bit) \details Executes a Unprivileged STRT instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) { __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); } #else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ /** \brief Signed Saturate \details Saturates a signed value. \param [in] value Value to be saturated \param [in] sat Bit position to saturate to (1..32) \return Saturated value */ __STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) { if ((sat >= 1U) && (sat <= 32U)) { const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); const int32_t min = -1 - max ; if (val > max) { return max; } else if (val < min) { return min; } } return val; } /** \brief Unsigned Saturate \details Saturates an unsigned value. \param [in] value Value to be saturated \param [in] sat Bit position to saturate to (0..31) \return Saturated value */ __STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) { if (sat <= 31U) { const uint32_t max = ((1U << sat) - 1U); if (val > (int32_t)max) { return max; } else if (val < 0) { return 0U; } } return (uint32_t)val; } #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) /** \brief Load-Acquire (8 bit) \details Executes a LDAB instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ __STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) { uint32_t result; __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); return ((uint8_t) result); } /** \brief Load-Acquire (16 bit) \details Executes a LDAH instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ __STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) { uint32_t result; __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); return ((uint16_t) result); } /** \brief Load-Acquire (32 bit) \details Executes a LDA instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ __STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) { uint32_t result; __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); return(result); } /** \brief Store-Release (8 bit) \details Executes a STLB instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) { __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief Store-Release (16 bit) \details Executes a STLH instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) { __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief Store-Release (32 bit) \details Executes a STL instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) { __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief Load-Acquire Exclusive (8 bit) \details Executes a LDAB exclusive instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ #define __LDAEXB (uint8_t)__builtin_arm_ldaex /** \brief Load-Acquire Exclusive (16 bit) \details Executes a LDAH exclusive instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ #define __LDAEXH (uint16_t)__builtin_arm_ldaex /** \brief Load-Acquire Exclusive (32 bit) \details Executes a LDA exclusive instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ #define __LDAEX (uint32_t)__builtin_arm_ldaex /** \brief Store-Release Exclusive (8 bit) \details Executes a STLB exclusive instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ #define __STLEXB (uint32_t)__builtin_arm_stlex /** \brief Store-Release Exclusive (16 bit) \details Executes a STLH exclusive instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ #define __STLEXH (uint32_t)__builtin_arm_stlex /** \brief Store-Release Exclusive (32 bit) \details Executes a STL exclusive instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ #define __STLEX (uint32_t)__builtin_arm_stlex #endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ /*@}*/ /* end of group CMSIS_Core_InstructionInterface */ /* ################### Compiler specific Intrinsics ########################### */ /** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics Access to dedicated SIMD instructions @{ */ #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) #define __SADD8 __builtin_arm_sadd8 #define __QADD8 __builtin_arm_qadd8 #define __SHADD8 __builtin_arm_shadd8 #define __UADD8 __builtin_arm_uadd8 #define __UQADD8 __builtin_arm_uqadd8 #define __UHADD8 __builtin_arm_uhadd8 #define __SSUB8 __builtin_arm_ssub8 #define __QSUB8 __builtin_arm_qsub8 #define __SHSUB8 __builtin_arm_shsub8 #define __USUB8 __builtin_arm_usub8 #define __UQSUB8 __builtin_arm_uqsub8 #define __UHSUB8 __builtin_arm_uhsub8 #define __SADD16 __builtin_arm_sadd16 #define __QADD16 __builtin_arm_qadd16 #define __SHADD16 __builtin_arm_shadd16 #define __UADD16 __builtin_arm_uadd16 #define __UQADD16 __builtin_arm_uqadd16 #define __UHADD16 __builtin_arm_uhadd16 #define __SSUB16 __builtin_arm_ssub16 #define __QSUB16 __builtin_arm_qsub16 #define __SHSUB16 __builtin_arm_shsub16 #define __USUB16 __builtin_arm_usub16 #define __UQSUB16 __builtin_arm_uqsub16 #define __UHSUB16 __builtin_arm_uhsub16 #define __SASX __builtin_arm_sasx #define __QASX __builtin_arm_qasx #define __SHASX __builtin_arm_shasx #define __UASX __builtin_arm_uasx #define __UQASX __builtin_arm_uqasx #define __UHASX __builtin_arm_uhasx #define __SSAX __builtin_arm_ssax #define __QSAX __builtin_arm_qsax #define __SHSAX __builtin_arm_shsax #define __USAX __builtin_arm_usax #define __UQSAX __builtin_arm_uqsax #define __UHSAX __builtin_arm_uhsax #define __USAD8 __builtin_arm_usad8 #define __USADA8 __builtin_arm_usada8 #define __SSAT16 __builtin_arm_ssat16 #define __USAT16 __builtin_arm_usat16 #define __UXTB16 __builtin_arm_uxtb16 #define __UXTAB16 __builtin_arm_uxtab16 #define __SXTB16 __builtin_arm_sxtb16 #define __SXTAB16 __builtin_arm_sxtab16 #define __SMUAD __builtin_arm_smuad #define __SMUADX __builtin_arm_smuadx #define __SMLAD __builtin_arm_smlad #define __SMLADX __builtin_arm_smladx #define __SMLALD __builtin_arm_smlald #define __SMLALDX __builtin_arm_smlaldx #define __SMUSD __builtin_arm_smusd #define __SMUSDX __builtin_arm_smusdx #define __SMLSD __builtin_arm_smlsd #define __SMLSDX __builtin_arm_smlsdx #define __SMLSLD __builtin_arm_smlsld #define __SMLSLDX __builtin_arm_smlsldx #define __SEL __builtin_arm_sel #define __QADD __builtin_arm_qadd #define __QSUB __builtin_arm_qsub #define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) #define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) __STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) { int32_t result; __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); return(result); } #endif /* (__ARM_FEATURE_DSP == 1) */ /*@} end of group CMSIS_SIMD_intrinsics */ #endif /* __CMSIS_ARMCLANG_H */ ================================================ FILE: 3rd_party/CMSIS/Include/cmsis_armclang_ltm.h ================================================ /**************************************************************************//** * @file cmsis_armclang_ltm.h * @brief CMSIS compiler armclang (Arm Compiler 6) header file * @version V1.2.0 * @date 08. May 2019 ******************************************************************************/ /* * Copyright (c) 2018-2019 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ #ifndef __CMSIS_ARMCLANG_H #define __CMSIS_ARMCLANG_H #pragma clang system_header /* treat file as system include file */ #ifndef __ARM_COMPAT_H #include /* Compatibility header for Arm Compiler 5 intrinsics */ #endif /* CMSIS compiler specific defines */ #ifndef __ASM #define __ASM __asm #endif #ifndef __INLINE #define __INLINE __inline #endif #ifndef __STATIC_INLINE #define __STATIC_INLINE static __inline #endif #ifndef __STATIC_FORCEINLINE #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline #endif #ifndef __NO_RETURN #define __NO_RETURN __attribute__((__noreturn__)) #endif #ifndef __USED #define __USED __attribute__((used)) #endif #ifndef __WEAK #define __WEAK __attribute__((weak)) #endif #ifndef __PACKED #define __PACKED __attribute__((packed, aligned(1))) #endif #ifndef __PACKED_STRUCT #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) #endif #ifndef __PACKED_UNION #define __PACKED_UNION union __attribute__((packed, aligned(1))) #endif #ifndef __UNALIGNED_UINT32 /* deprecated */ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpacked" /*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ struct __attribute__((packed)) T_UINT32 { uint32_t v; }; #pragma clang diagnostic pop #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) #endif #ifndef __UNALIGNED_UINT16_WRITE #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpacked" /*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; #pragma clang diagnostic pop #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT16_READ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpacked" /*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; #pragma clang diagnostic pop #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) #endif #ifndef __UNALIGNED_UINT32_WRITE #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpacked" /*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; #pragma clang diagnostic pop #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT32_READ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpacked" /*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; #pragma clang diagnostic pop #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) #endif #ifndef __ALIGNED #define __ALIGNED(x) __attribute__((aligned(x))) #endif #ifndef __RESTRICT #define __RESTRICT __restrict #endif #ifndef __COMPILER_BARRIER #define __COMPILER_BARRIER() __ASM volatile("":::"memory") #endif /* ######################### Startup and Lowlevel Init ######################## */ #ifndef __PROGRAM_START #define __PROGRAM_START __main #endif #ifndef __INITIAL_SP #define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit #endif #ifndef __STACK_LIMIT #define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base #endif #ifndef __VECTOR_TABLE #define __VECTOR_TABLE __Vectors #endif #ifndef __VECTOR_TABLE_ATTRIBUTE #define __VECTOR_TABLE_ATTRIBUTE __attribute((used, section("RESET"))) #endif /* ########################### Core Function Access ########################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions @{ */ /** \brief Enable IRQ Interrupts \details Enables IRQ interrupts by clearing the I-bit in the CPSR. Can only be executed in Privileged modes. */ /* intrinsic void __enable_irq(); see arm_compat.h */ /** \brief Disable IRQ Interrupts \details Disables IRQ interrupts by setting the I-bit in the CPSR. Can only be executed in Privileged modes. */ /* intrinsic void __disable_irq(); see arm_compat.h */ /** \brief Get Control Register \details Returns the content of the Control Register. \return Control Register value */ __STATIC_FORCEINLINE uint32_t __get_CONTROL(void) { uint32_t result; __ASM volatile ("MRS %0, control" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Control Register (non-secure) \details Returns the content of the non-secure Control Register when in secure mode. \return non-secure Control Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) { uint32_t result; __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Control Register \details Writes the given value to the Control Register. \param [in] control Control Register value to set */ __STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) { __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Control Register (non-secure) \details Writes the given value to the non-secure Control Register when in secure state. \param [in] control Control Register value to set */ __STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) { __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); } #endif /** \brief Get IPSR Register \details Returns the content of the IPSR Register. \return IPSR Register value */ __STATIC_FORCEINLINE uint32_t __get_IPSR(void) { uint32_t result; __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); return(result); } /** \brief Get APSR Register \details Returns the content of the APSR Register. \return APSR Register value */ __STATIC_FORCEINLINE uint32_t __get_APSR(void) { uint32_t result; __ASM volatile ("MRS %0, apsr" : "=r" (result) ); return(result); } /** \brief Get xPSR Register \details Returns the content of the xPSR Register. \return xPSR Register value */ __STATIC_FORCEINLINE uint32_t __get_xPSR(void) { uint32_t result; __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); return(result); } /** \brief Get Process Stack Pointer \details Returns the current value of the Process Stack Pointer (PSP). \return PSP Register value */ __STATIC_FORCEINLINE uint32_t __get_PSP(void) { uint32_t result; __ASM volatile ("MRS %0, psp" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Process Stack Pointer (non-secure) \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. \return PSP Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) { uint32_t result; __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Process Stack Pointer \details Assigns the given value to the Process Stack Pointer (PSP). \param [in] topOfProcStack Process Stack Pointer value to set */ __STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) { __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Process Stack Pointer (non-secure) \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. \param [in] topOfProcStack Process Stack Pointer value to set */ __STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) { __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); } #endif /** \brief Get Main Stack Pointer \details Returns the current value of the Main Stack Pointer (MSP). \return MSP Register value */ __STATIC_FORCEINLINE uint32_t __get_MSP(void) { uint32_t result; __ASM volatile ("MRS %0, msp" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Main Stack Pointer (non-secure) \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. \return MSP Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) { uint32_t result; __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Main Stack Pointer \details Assigns the given value to the Main Stack Pointer (MSP). \param [in] topOfMainStack Main Stack Pointer value to set */ __STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) { __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Main Stack Pointer (non-secure) \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. \param [in] topOfMainStack Main Stack Pointer value to set */ __STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) { __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); } #endif #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Stack Pointer (non-secure) \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. \return SP Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) { uint32_t result; __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); return(result); } /** \brief Set Stack Pointer (non-secure) \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. \param [in] topOfStack Stack Pointer value to set */ __STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) { __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); } #endif /** \brief Get Priority Mask \details Returns the current state of the priority mask bit from the Priority Mask Register. \return Priority Mask value */ __STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) { uint32_t result; __ASM volatile ("MRS %0, primask" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Priority Mask (non-secure) \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. \return Priority Mask value */ __STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) { uint32_t result; __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Priority Mask \details Assigns the given value to the Priority Mask Register. \param [in] priMask Priority Mask */ __STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) { __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Priority Mask (non-secure) \details Assigns the given value to the non-secure Priority Mask Register when in secure state. \param [in] priMask Priority Mask */ __STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) { __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); } #endif #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) /** \brief Enable FIQ \details Enables FIQ interrupts by clearing the F-bit in the CPSR. Can only be executed in Privileged modes. */ #define __enable_fault_irq __enable_fiq /* see arm_compat.h */ /** \brief Disable FIQ \details Disables FIQ interrupts by setting the F-bit in the CPSR. Can only be executed in Privileged modes. */ #define __disable_fault_irq __disable_fiq /* see arm_compat.h */ /** \brief Get Base Priority \details Returns the current value of the Base Priority register. \return Base Priority register value */ __STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) { uint32_t result; __ASM volatile ("MRS %0, basepri" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Base Priority (non-secure) \details Returns the current value of the non-secure Base Priority register when in secure state. \return Base Priority register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) { uint32_t result; __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Base Priority \details Assigns the given value to the Base Priority register. \param [in] basePri Base Priority value to set */ __STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) { __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Base Priority (non-secure) \details Assigns the given value to the non-secure Base Priority register when in secure state. \param [in] basePri Base Priority value to set */ __STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) { __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); } #endif /** \brief Set Base Priority with condition \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, or the new value increases the BASEPRI priority level. \param [in] basePri Base Priority value to set */ __STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) { __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); } /** \brief Get Fault Mask \details Returns the current value of the Fault Mask register. \return Fault Mask register value */ __STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) { uint32_t result; __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Fault Mask (non-secure) \details Returns the current value of the non-secure Fault Mask register when in secure state. \return Fault Mask register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) { uint32_t result; __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Fault Mask \details Assigns the given value to the Fault Mask register. \param [in] faultMask Fault Mask value to set */ __STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) { __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Fault Mask (non-secure) \details Assigns the given value to the non-secure Fault Mask register when in secure state. \param [in] faultMask Fault Mask value to set */ __STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) { __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); } #endif #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) /** \brief Get Process Stack Pointer Limit Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence zero is returned always in non-secure mode. \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). \return PSPLIM Register value */ __STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure PSPLIM is RAZ/WI return 0U; #else uint32_t result; __ASM volatile ("MRS %0, psplim" : "=r" (result) ); return result; #endif } #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Process Stack Pointer Limit (non-secure) Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence zero is returned always in non-secure mode. \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. \return PSPLIM Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) // without main extensions, the non-secure PSPLIM is RAZ/WI return 0U; #else uint32_t result; __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); return result; #endif } #endif /** \brief Set Process Stack Pointer Limit Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence the write is silently ignored in non-secure mode. \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set */ __STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure PSPLIM is RAZ/WI (void)ProcStackPtrLimit; #else __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); #endif } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Process Stack Pointer (non-secure) Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence the write is silently ignored in non-secure mode. \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set */ __STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) // without main extensions, the non-secure PSPLIM is RAZ/WI (void)ProcStackPtrLimit; #else __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); #endif } #endif /** \brief Get Main Stack Pointer Limit Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence zero is returned always. \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). \return MSPLIM Register value */ __STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure MSPLIM is RAZ/WI return 0U; #else uint32_t result; __ASM volatile ("MRS %0, msplim" : "=r" (result) ); return result; #endif } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Main Stack Pointer Limit (non-secure) Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence zero is returned always. \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. \return MSPLIM Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) // without main extensions, the non-secure MSPLIM is RAZ/WI return 0U; #else uint32_t result; __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); return result; #endif } #endif /** \brief Set Main Stack Pointer Limit Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence the write is silently ignored. \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set */ __STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure MSPLIM is RAZ/WI (void)MainStackPtrLimit; #else __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); #endif } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Main Stack Pointer Limit (non-secure) Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence the write is silently ignored. \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. \param [in] MainStackPtrLimit Main Stack Pointer value to set */ __STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) // without main extensions, the non-secure MSPLIM is RAZ/WI (void)MainStackPtrLimit; #else __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); #endif } #endif #endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ /** \brief Get FPSCR \details Returns the current value of the Floating Point Status/Control register. \return Floating Point Status/Control register value */ #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) #define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr #else #define __get_FPSCR() ((uint32_t)0U) #endif /** \brief Set FPSCR \details Assigns the given value to the Floating Point Status/Control register. \param [in] fpscr Floating Point Status/Control value to set */ #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) #define __set_FPSCR __builtin_arm_set_fpscr #else #define __set_FPSCR(x) ((void)(x)) #endif /*@} end of CMSIS_Core_RegAccFunctions */ /* ########################## Core Instruction Access ######################### */ /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface Access to dedicated instructions @{ */ /* Define macros for porting to both thumb1 and thumb2. * For thumb1, use low register (r0-r7), specified by constraint "l" * Otherwise, use general registers, specified by constraint "r" */ #if defined (__thumb__) && !defined (__thumb2__) #define __CMSIS_GCC_OUT_REG(r) "=l" (r) #define __CMSIS_GCC_USE_REG(r) "l" (r) #else #define __CMSIS_GCC_OUT_REG(r) "=r" (r) #define __CMSIS_GCC_USE_REG(r) "r" (r) #endif /** \brief No Operation \details No Operation does nothing. This instruction can be used for code alignment purposes. */ #define __NOP __builtin_arm_nop /** \brief Wait For Interrupt \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. */ #define __WFI __builtin_arm_wfi /** \brief Wait For Event \details Wait For Event is a hint instruction that permits the processor to enter a low-power state until one of a number of events occurs. */ #define __WFE __builtin_arm_wfe /** \brief Send Event \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. */ #define __SEV __builtin_arm_sev /** \brief Instruction Synchronization Barrier \details Instruction Synchronization Barrier flushes the pipeline in the processor, so that all instructions following the ISB are fetched from cache or memory, after the instruction has been completed. */ #define __ISB() __builtin_arm_isb(0xF) /** \brief Data Synchronization Barrier \details Acts as a special kind of Data Memory Barrier. It completes when all explicit memory accesses before this instruction complete. */ #define __DSB() __builtin_arm_dsb(0xF) /** \brief Data Memory Barrier \details Ensures the apparent order of the explicit memory operations before and after the instruction, without ensuring their completion. */ #define __DMB() __builtin_arm_dmb(0xF) /** \brief Reverse byte order (32 bit) \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. \param [in] value Value to reverse \return Reversed value */ #define __REV(value) __builtin_bswap32(value) /** \brief Reverse byte order (16 bit) \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. \param [in] value Value to reverse \return Reversed value */ #define __REV16(value) __ROR(__REV(value), 16) /** \brief Reverse byte order (16 bit) \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. \param [in] value Value to reverse \return Reversed value */ #define __REVSH(value) (int16_t)__builtin_bswap16(value) /** \brief Rotate Right in unsigned value (32 bit) \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. \param [in] op1 Value to rotate \param [in] op2 Number of Bits to rotate \return Rotated value */ __STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) { op2 %= 32U; if (op2 == 0U) { return op1; } return (op1 >> op2) | (op1 << (32U - op2)); } /** \brief Breakpoint \details Causes the processor to enter Debug state. Debug tools can use this to investigate system state when the instruction at a particular address is reached. \param [in] value is ignored by the processor. If required, a debugger can use it to store additional information about the breakpoint. */ #define __BKPT(value) __ASM volatile ("bkpt "#value) /** \brief Reverse bit order of value \details Reverses the bit order of the given value. \param [in] value Value to reverse \return Reversed value */ #define __RBIT __builtin_arm_rbit /** \brief Count leading zeros \details Counts the number of leading zeros of a data value. \param [in] value Value to count the leading zeros \return number of leading zeros in value */ __STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) { /* Even though __builtin_clz produces a CLZ instruction on ARM, formally __builtin_clz(0) is undefined behaviour, so handle this case specially. This guarantees ARM-compatible results if happening to compile on a non-ARM target, and ensures the compiler doesn't decide to activate any optimisations using the logic "value was passed to __builtin_clz, so it is non-zero". ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a single CLZ instruction. */ if (value == 0U) { return 32U; } return __builtin_clz(value); } #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) /** \brief LDR Exclusive (8 bit) \details Executes a exclusive LDR instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ #define __LDREXB (uint8_t)__builtin_arm_ldrex /** \brief LDR Exclusive (16 bit) \details Executes a exclusive LDR instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ #define __LDREXH (uint16_t)__builtin_arm_ldrex /** \brief LDR Exclusive (32 bit) \details Executes a exclusive LDR instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ #define __LDREXW (uint32_t)__builtin_arm_ldrex /** \brief STR Exclusive (8 bit) \details Executes a exclusive STR instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ #define __STREXB (uint32_t)__builtin_arm_strex /** \brief STR Exclusive (16 bit) \details Executes a exclusive STR instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ #define __STREXH (uint32_t)__builtin_arm_strex /** \brief STR Exclusive (32 bit) \details Executes a exclusive STR instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ #define __STREXW (uint32_t)__builtin_arm_strex /** \brief Remove the exclusive lock \details Removes the exclusive lock which is created by LDREX. */ #define __CLREX __builtin_arm_clrex #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) /** \brief Signed Saturate \details Saturates a signed value. \param [in] value Value to be saturated \param [in] sat Bit position to saturate to (1..32) \return Saturated value */ #define __SSAT __builtin_arm_ssat /** \brief Unsigned Saturate \details Saturates an unsigned value. \param [in] value Value to be saturated \param [in] sat Bit position to saturate to (0..31) \return Saturated value */ #define __USAT __builtin_arm_usat /** \brief Rotate Right with Extend (32 bit) \details Moves each bit of a bitstring right by one bit. The carry input is shifted in at the left end of the bitstring. \param [in] value Value to rotate \return Rotated value */ __STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) { uint32_t result; __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); return(result); } /** \brief LDRT Unprivileged (8 bit) \details Executes a Unprivileged LDRT instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ __STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) { uint32_t result; __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); return ((uint8_t) result); /* Add explicit type cast here */ } /** \brief LDRT Unprivileged (16 bit) \details Executes a Unprivileged LDRT instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ __STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) { uint32_t result; __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); return ((uint16_t) result); /* Add explicit type cast here */ } /** \brief LDRT Unprivileged (32 bit) \details Executes a Unprivileged LDRT instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ __STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) { uint32_t result; __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); return(result); } /** \brief STRT Unprivileged (8 bit) \details Executes a Unprivileged STRT instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) { __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief STRT Unprivileged (16 bit) \details Executes a Unprivileged STRT instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) { __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief STRT Unprivileged (32 bit) \details Executes a Unprivileged STRT instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) { __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); } #else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ /** \brief Signed Saturate \details Saturates a signed value. \param [in] value Value to be saturated \param [in] sat Bit position to saturate to (1..32) \return Saturated value */ __STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) { if ((sat >= 1U) && (sat <= 32U)) { const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); const int32_t min = -1 - max ; if (val > max) { return max; } else if (val < min) { return min; } } return val; } /** \brief Unsigned Saturate \details Saturates an unsigned value. \param [in] value Value to be saturated \param [in] sat Bit position to saturate to (0..31) \return Saturated value */ __STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) { if (sat <= 31U) { const uint32_t max = ((1U << sat) - 1U); if (val > (int32_t)max) { return max; } else if (val < 0) { return 0U; } } return (uint32_t)val; } #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) /** \brief Load-Acquire (8 bit) \details Executes a LDAB instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ __STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) { uint32_t result; __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); return ((uint8_t) result); } /** \brief Load-Acquire (16 bit) \details Executes a LDAH instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ __STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) { uint32_t result; __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); return ((uint16_t) result); } /** \brief Load-Acquire (32 bit) \details Executes a LDA instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ __STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) { uint32_t result; __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); return(result); } /** \brief Store-Release (8 bit) \details Executes a STLB instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) { __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief Store-Release (16 bit) \details Executes a STLH instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) { __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief Store-Release (32 bit) \details Executes a STL instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) { __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief Load-Acquire Exclusive (8 bit) \details Executes a LDAB exclusive instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ #define __LDAEXB (uint8_t)__builtin_arm_ldaex /** \brief Load-Acquire Exclusive (16 bit) \details Executes a LDAH exclusive instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ #define __LDAEXH (uint16_t)__builtin_arm_ldaex /** \brief Load-Acquire Exclusive (32 bit) \details Executes a LDA exclusive instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ #define __LDAEX (uint32_t)__builtin_arm_ldaex /** \brief Store-Release Exclusive (8 bit) \details Executes a STLB exclusive instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ #define __STLEXB (uint32_t)__builtin_arm_stlex /** \brief Store-Release Exclusive (16 bit) \details Executes a STLH exclusive instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ #define __STLEXH (uint32_t)__builtin_arm_stlex /** \brief Store-Release Exclusive (32 bit) \details Executes a STL exclusive instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ #define __STLEX (uint32_t)__builtin_arm_stlex #endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ /*@}*/ /* end of group CMSIS_Core_InstructionInterface */ /* ################### Compiler specific Intrinsics ########################### */ /** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics Access to dedicated SIMD instructions @{ */ #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) __STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); return(result); } #define __SSAT16(ARG1,ARG2) \ ({ \ int32_t __RES, __ARG1 = (ARG1); \ __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ __RES; \ }) #define __USAT16(ARG1,ARG2) \ ({ \ uint32_t __RES, __ARG1 = (ARG1); \ __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ __RES; \ }) __STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) { uint32_t result; __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); return(result); } __STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) { uint32_t result; __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); return(result); } __STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); return(result); } __STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; uint64_t w64; } llr; llr.w64 = acc; #ifndef __ARMEB__ /* Little endian */ __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); #else /* Big endian */ __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); #endif return(llr.w64); } __STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; uint64_t w64; } llr; llr.w64 = acc; #ifndef __ARMEB__ /* Little endian */ __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); #else /* Big endian */ __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); #endif return(llr.w64); } __STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); return(result); } __STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; uint64_t w64; } llr; llr.w64 = acc; #ifndef __ARMEB__ /* Little endian */ __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); #else /* Big endian */ __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); #endif return(llr.w64); } __STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; uint64_t w64; } llr; llr.w64 = acc; #ifndef __ARMEB__ /* Little endian */ __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); #else /* Big endian */ __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); #endif return(llr.w64); } __STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) { int32_t result; __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) { int32_t result; __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } #define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) #define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) __STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) { int32_t result; __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); return(result); } #endif /* (__ARM_FEATURE_DSP == 1) */ /*@} end of group CMSIS_SIMD_intrinsics */ #endif /* __CMSIS_ARMCLANG_H */ ================================================ FILE: 3rd_party/CMSIS/Include/cmsis_ccs.h ================================================ //***************************************************************************** // // Copyright (C) 2012 - 2017 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // MSP432 Family CMSIS Definitions // //**************************************************************************** #ifndef CMSIS_CCS_H_ #define CMSIS_CCS_H_ //***************************************************************************** // CMSIS-compatible instruction calls //***************************************************************************** // // v5e, v6, Cortex-M3, Cortex-M4, Cortex-R4, and Cortex-A8 compiler intrinsics // #define __CLZ _norm #define __SXTB _sxtb #define __SXTH _sxth #define __UXTB _uxtb #define __UXTH _uxth // CCS supports intrinsics to take advantage of the shift operand left/right // before saturation extension of SSAT, but CMSIS does not take advantage // of those, so tell the compiler to use a sat & shift left with a shift // value of 0 whenever it encounters an SSAT #define __SSAT(VAL, BITPOS) \ _ssatl(VAL , 0, BITPOS) // // Only define M4 based intrinsics if we're not using an M4 // #if defined (__TI_TMS470_V7M4__) // // Add definitions for enable and disable interrupts // #if defined (__TI_COMPILER_VERSION__) #if (__TI_COMPILER_VERSION__ >= 5002000) #define __enable_irq _enable_IRQ #define __disable_irq _disable_IRQ // No Operation #define __NOP __nop // Data Synchronization Barrier #define __DSB _dsb #define __ISB _isb #define __WFI() __asm(" wfi") #elif (__TI_COMPILER_VERSION__ >= 4009000) #define __enable_fault_irq _enable_interrupts #define __disable_fault_irq _disable_interrupts // No Operation __attribute__( ( always_inline ) ) static inline void __nop(void) { __asm(" nop"); } __attribute__( ( always_inline ) ) static inline void __NOP(void) { __asm(" nop"); } // Data Synchronization Barrier __attribute__( ( always_inline ) ) static inline void __DSB(void) { __asm(" dsb"); } __attribute__( ( always_inline ) ) static inline void __ISB(void) { __asm(" isb"); } __attribute__( ( always_inline ) ) static inline void __WFI(void) { __asm(" wfi"); } #endif /*__TI_COMPILER_VERSION__ version*/ #endif /*__TI_COMPILER_VERSION__*/ // // V5E, V6, Cortex-M4, Cortex-R4, and Cortex-A8 compiler intrinsics // #define __ROR __ror #define __SXTB16(src) _sxtb16((src),0) #define __QADD _sadd #define __QDADD _sdadd #define __QDSUB _sdsub #define __SMLABB _smlabb #define __SMLABT _smlabt #define __SMLALBB _smlalbb #define __SMLALBT _smlalbt #define __SMLALTB _smlaltb #define __SMLALTT _smlaltt #define __SMLATB _smlatb #define __SMLATT _smlatt #define __SMLAWB _smlawb #define __SMLAWT _smlawt #define __SMULBB _smulbb #define __SMULBT _smulbt #define __SMULTB _smultb #define __SMULTT _smultt #define __SMULWB _smulwb #define __SMULWT _smulwt #define __QSUB _ssub #define __SUBC _subc // // v6, Cortex-M4, Cortex-R4, and Cortex-A8 compiler intrinsics // #define __SHASX _shaddsubx #define __SHSAX _shsubaddx #define __PKHBT _pkhbt #define __PKHTB _pkhtb #define __QADD16 _qadd16 #define __QADD8 _qadd8 #define __QSUB16 _qsub16 #define __QSUB8 _qsub8 #define __QASX _saddsubx #define __QSAX _qsubaddx #define __SADD16 _sadd16 #define __SADD8 _sadd8 #define __SASX _saddsubx #define __SEL _sel #define __SHADD16 _shadd16 #define __SHADD8 _shadd8 #define __SHSUB16 _shsub16 #define __SHSUB8 _shsub8 #define __SMLAD _smlad #define __SMLADX _smladx #define __SMLALD(src1, src2, accumulator) _smlald(accumulator, src1, src2) #define __SMLALDX _smlaldx #define __SMLSD _smlsd #define __SMLSDX _smlsdx #define __SMLSLD _smlsld #define __SMLSLDX _smlsldx #define __SMMLA _smmla #define __SMMLAR _smmlar #define __SMMLS _smmls #define __SMMLSR _smmlsr #define __SMMUL _smmul #define __SMMULR _smmulr #define __SMUAD _smuad #define __SMUADX _smuadx #define __SMUSD _smusd #define __SMUSDX _smusdx #define __SSAT16 _ssat16 #define __SSUB16 _ssub16 #define __SSUB8 _ssub8 #define __SSAX _ssubaddx #define __SXTAB _sxtab #define __SXTAB16 _sxtab16 #define __SXTAH _sxtah #define __UMAAL _umaal #define __UADD16 _uadd16 #define __UADD8 _uadd8 #define __UHADD16 _uhadd16 #define __UHADD8 _uhadd8 #define __UASX _uaddsubx #define __UHSUB16 _uhsub16 #define __UHSUB8 _uhsub8 #define __UQADD16 _uqadd16 #define __UQADD8 _uqadd8 #define __UQASX _uqaddsubx #define __UQSUB16 _uqsub16 #define __UQSUB8 _uqsub8 #define __UQSAX _uqsubaddx #define __USAD8 _usad8 #define __USAT16 _usat16 #define __USUB16 _usub16 #define __USUB8 _usub8 #define __USAX _usubaddx #define __UXTAB _uxtab #define __UXTAB16 _uxtab16 #define __UXTAH _uxtah #define __UXTB16 _uxtb16 #endif /*__TI_TMS470_V7M4__*/ #endif /*CMSIS_CCS_H_*/ ================================================ FILE: 3rd_party/CMSIS/Include/cmsis_compiler.h ================================================ /**************************************************************************//** * @file cmsis_compiler.h * @brief CMSIS compiler generic header file * @version V5.1.0 * @date 09. October 2018 ******************************************************************************/ /* * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef __CMSIS_COMPILER_H #define __CMSIS_COMPILER_H #include /* * Arm Compiler 4/5 */ #if defined ( __CC_ARM ) #include "cmsis_armcc.h" /* * Arm Compiler 6.6 LTM (armclang) */ #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100) #include "cmsis_armclang_ltm.h" /* * Arm Compiler above 6.10.1 (armclang) */ #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) #include "cmsis_armclang.h" /* * GNU Compiler */ #elif defined ( __GNUC__ ) #include "cmsis_gcc.h" /* * IAR Compiler */ #elif defined ( __ICCARM__ ) #include /* * TI Arm Compiler */ #elif defined ( __TI_ARM__ ) #include #ifndef __ASM #define __ASM __asm #endif #ifndef __INLINE #define __INLINE inline #endif #ifndef __STATIC_INLINE #define __STATIC_INLINE static inline #endif #ifndef __STATIC_FORCEINLINE #define __STATIC_FORCEINLINE __STATIC_INLINE #endif #ifndef __NO_RETURN #define __NO_RETURN __attribute__((noreturn)) #endif #ifndef __USED #define __USED __attribute__((used)) #endif #ifndef __WEAK #define __WEAK __attribute__((weak)) #endif #ifndef __PACKED #define __PACKED __attribute__((packed)) #endif #ifndef __PACKED_STRUCT #define __PACKED_STRUCT struct __attribute__((packed)) #endif #ifndef __PACKED_UNION #define __PACKED_UNION union __attribute__((packed)) #endif #ifndef __UNALIGNED_UINT32 /* deprecated */ struct __attribute__((packed)) T_UINT32 { uint32_t v; }; #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) #endif #ifndef __UNALIGNED_UINT16_WRITE __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT16_READ __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) #endif #ifndef __UNALIGNED_UINT32_WRITE __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT32_READ __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) #endif #ifndef __ALIGNED #define __ALIGNED(x) __attribute__((aligned(x))) #endif #ifndef __RESTRICT #define __RESTRICT __restrict #endif #ifndef __COMPILER_BARRIER #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. #define __COMPILER_BARRIER() (void)0 #endif /* * TASKING Compiler */ #elif defined ( __TASKING__ ) /* * The CMSIS functions have been implemented as intrinsics in the compiler. * Please use "carm -?i" to get an up to date list of all intrinsics, * Including the CMSIS ones. */ #ifndef __ASM #define __ASM __asm #endif #ifndef __INLINE #define __INLINE inline #endif #ifndef __STATIC_INLINE #define __STATIC_INLINE static inline #endif #ifndef __STATIC_FORCEINLINE #define __STATIC_FORCEINLINE __STATIC_INLINE #endif #ifndef __NO_RETURN #define __NO_RETURN __attribute__((noreturn)) #endif #ifndef __USED #define __USED __attribute__((used)) #endif #ifndef __WEAK #define __WEAK __attribute__((weak)) #endif #ifndef __PACKED #define __PACKED __packed__ #endif #ifndef __PACKED_STRUCT #define __PACKED_STRUCT struct __packed__ #endif #ifndef __PACKED_UNION #define __PACKED_UNION union __packed__ #endif #ifndef __UNALIGNED_UINT32 /* deprecated */ struct __packed__ T_UINT32 { uint32_t v; }; #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) #endif #ifndef __UNALIGNED_UINT16_WRITE __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT16_READ __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) #endif #ifndef __UNALIGNED_UINT32_WRITE __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT32_READ __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) #endif #ifndef __ALIGNED #define __ALIGNED(x) __align(x) #endif #ifndef __RESTRICT #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. #define __RESTRICT #endif #ifndef __COMPILER_BARRIER #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. #define __COMPILER_BARRIER() (void)0 #endif /* * COSMIC Compiler */ #elif defined ( __CSMC__ ) #include #ifndef __ASM #define __ASM _asm #endif #ifndef __INLINE #define __INLINE inline #endif #ifndef __STATIC_INLINE #define __STATIC_INLINE static inline #endif #ifndef __STATIC_FORCEINLINE #define __STATIC_FORCEINLINE __STATIC_INLINE #endif #ifndef __NO_RETURN // NO RETURN is automatically detected hence no warning here #define __NO_RETURN #endif #ifndef __USED #warning No compiler specific solution for __USED. __USED is ignored. #define __USED #endif #ifndef __WEAK #define __WEAK __weak #endif #ifndef __PACKED #define __PACKED @packed #endif #ifndef __PACKED_STRUCT #define __PACKED_STRUCT @packed struct #endif #ifndef __PACKED_UNION #define __PACKED_UNION @packed union #endif #ifndef __UNALIGNED_UINT32 /* deprecated */ @packed struct T_UINT32 { uint32_t v; }; #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) #endif #ifndef __UNALIGNED_UINT16_WRITE __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT16_READ __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) #endif #ifndef __UNALIGNED_UINT32_WRITE __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT32_READ __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) #endif #ifndef __ALIGNED #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. #define __ALIGNED(x) #endif #ifndef __RESTRICT #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. #define __RESTRICT #endif #ifndef __COMPILER_BARRIER #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. #define __COMPILER_BARRIER() (void)0 #endif #else #error Unknown compiler. #endif #endif /* __CMSIS_COMPILER_H */ ================================================ FILE: 3rd_party/CMSIS/Include/cmsis_gcc.h ================================================ /**************************************************************************//** * @file cmsis_gcc.h * @brief CMSIS compiler GCC header file * @version V5.2.0 * @date 08. May 2019 ******************************************************************************/ /* * Copyright (c) 2009-2019 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef __CMSIS_GCC_H #define __CMSIS_GCC_H /* ignore some GCC warnings */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsign-conversion" #pragma GCC diagnostic ignored "-Wconversion" #pragma GCC diagnostic ignored "-Wunused-parameter" /* Fallback for __has_builtin */ #ifndef __has_builtin #define __has_builtin(x) (0) #endif /* CMSIS compiler specific defines */ #ifndef __ASM #define __ASM __asm #endif #ifndef __INLINE #define __INLINE inline #endif #ifndef __STATIC_INLINE #define __STATIC_INLINE static inline #endif #ifndef __STATIC_FORCEINLINE #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline #endif #ifndef __NO_RETURN #define __NO_RETURN __attribute__((__noreturn__)) #endif #ifndef __USED #define __USED __attribute__((used)) #endif #ifndef __WEAK #define __WEAK __attribute__((weak)) #endif #ifndef __PACKED #define __PACKED __attribute__((packed, aligned(1))) #endif #ifndef __PACKED_STRUCT #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) #endif #ifndef __PACKED_UNION #define __PACKED_UNION union __attribute__((packed, aligned(1))) #endif #ifndef __UNALIGNED_UINT32 /* deprecated */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpacked" #pragma GCC diagnostic ignored "-Wattributes" struct __attribute__((packed)) T_UINT32 { uint32_t v; }; #pragma GCC diagnostic pop #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) #endif #ifndef __UNALIGNED_UINT16_WRITE #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpacked" #pragma GCC diagnostic ignored "-Wattributes" __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; #pragma GCC diagnostic pop #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT16_READ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpacked" #pragma GCC diagnostic ignored "-Wattributes" __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; #pragma GCC diagnostic pop #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) #endif #ifndef __UNALIGNED_UINT32_WRITE #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpacked" #pragma GCC diagnostic ignored "-Wattributes" __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; #pragma GCC diagnostic pop #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT32_READ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpacked" #pragma GCC diagnostic ignored "-Wattributes" __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; #pragma GCC diagnostic pop #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) #endif #ifndef __ALIGNED #define __ALIGNED(x) __attribute__((aligned(x))) #endif #ifndef __RESTRICT #define __RESTRICT __restrict #endif #ifndef __COMPILER_BARRIER #define __COMPILER_BARRIER() __ASM volatile("":::"memory") #endif /* ######################### Startup and Lowlevel Init ######################## */ #ifndef __PROGRAM_START /** \brief Initializes data and bss sections \details This default implementations initialized all data and additional bss sections relying on .copy.table and .zero.table specified properly in the used linker script. */ __STATIC_FORCEINLINE __NO_RETURN void __cmsis_start(void) { extern void _start(void) __NO_RETURN; typedef struct { uint32_t const* src; uint32_t* dest; uint32_t wlen; } __copy_table_t; typedef struct { uint32_t* dest; uint32_t wlen; } __zero_table_t; extern const __copy_table_t __copy_table_start__; extern const __copy_table_t __copy_table_end__; extern const __zero_table_t __zero_table_start__; extern const __zero_table_t __zero_table_end__; for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) { for(uint32_t i=0u; iwlen; ++i) { pTable->dest[i] = pTable->src[i]; } } for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) { for(uint32_t i=0u; iwlen; ++i) { pTable->dest[i] = 0u; } } _start(); } #define __PROGRAM_START __cmsis_start #endif #ifndef __INITIAL_SP #define __INITIAL_SP __StackTop #endif #ifndef __STACK_LIMIT #define __STACK_LIMIT __StackLimit #endif #ifndef __VECTOR_TABLE #define __VECTOR_TABLE __Vectors #endif #ifndef __VECTOR_TABLE_ATTRIBUTE #define __VECTOR_TABLE_ATTRIBUTE __attribute((used, section(".vectors"))) #endif /* ########################### Core Function Access ########################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions @{ */ /** \brief Enable IRQ Interrupts \details Enables IRQ interrupts by clearing the I-bit in the CPSR. Can only be executed in Privileged modes. */ __STATIC_FORCEINLINE void __enable_irq(void) { __ASM volatile ("cpsie i" : : : "memory"); } /** \brief Disable IRQ Interrupts \details Disables IRQ interrupts by setting the I-bit in the CPSR. Can only be executed in Privileged modes. */ __STATIC_FORCEINLINE void __disable_irq(void) { __ASM volatile ("cpsid i" : : : "memory"); } /** \brief Get Control Register \details Returns the content of the Control Register. \return Control Register value */ __STATIC_FORCEINLINE uint32_t __get_CONTROL(void) { uint32_t result; __ASM volatile ("MRS %0, control" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Control Register (non-secure) \details Returns the content of the non-secure Control Register when in secure mode. \return non-secure Control Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) { uint32_t result; __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Control Register \details Writes the given value to the Control Register. \param [in] control Control Register value to set */ __STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) { __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Control Register (non-secure) \details Writes the given value to the non-secure Control Register when in secure state. \param [in] control Control Register value to set */ __STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) { __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); } #endif /** \brief Get IPSR Register \details Returns the content of the IPSR Register. \return IPSR Register value */ __STATIC_FORCEINLINE uint32_t __get_IPSR(void) { uint32_t result; __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); return(result); } /** \brief Get APSR Register \details Returns the content of the APSR Register. \return APSR Register value */ __STATIC_FORCEINLINE uint32_t __get_APSR(void) { uint32_t result; __ASM volatile ("MRS %0, apsr" : "=r" (result) ); return(result); } /** \brief Get xPSR Register \details Returns the content of the xPSR Register. \return xPSR Register value */ __STATIC_FORCEINLINE uint32_t __get_xPSR(void) { uint32_t result; __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); return(result); } /** \brief Get Process Stack Pointer \details Returns the current value of the Process Stack Pointer (PSP). \return PSP Register value */ __STATIC_FORCEINLINE uint32_t __get_PSP(void) { uint32_t result; __ASM volatile ("MRS %0, psp" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Process Stack Pointer (non-secure) \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. \return PSP Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) { uint32_t result; __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Process Stack Pointer \details Assigns the given value to the Process Stack Pointer (PSP). \param [in] topOfProcStack Process Stack Pointer value to set */ __STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) { __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Process Stack Pointer (non-secure) \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. \param [in] topOfProcStack Process Stack Pointer value to set */ __STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) { __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); } #endif /** \brief Get Main Stack Pointer \details Returns the current value of the Main Stack Pointer (MSP). \return MSP Register value */ __STATIC_FORCEINLINE uint32_t __get_MSP(void) { uint32_t result; __ASM volatile ("MRS %0, msp" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Main Stack Pointer (non-secure) \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. \return MSP Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) { uint32_t result; __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Main Stack Pointer \details Assigns the given value to the Main Stack Pointer (MSP). \param [in] topOfMainStack Main Stack Pointer value to set */ __STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) { __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Main Stack Pointer (non-secure) \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. \param [in] topOfMainStack Main Stack Pointer value to set */ __STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) { __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); } #endif #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Stack Pointer (non-secure) \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. \return SP Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) { uint32_t result; __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); return(result); } /** \brief Set Stack Pointer (non-secure) \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. \param [in] topOfStack Stack Pointer value to set */ __STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) { __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); } #endif /** \brief Get Priority Mask \details Returns the current state of the priority mask bit from the Priority Mask Register. \return Priority Mask value */ __STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) { uint32_t result; __ASM volatile ("MRS %0, primask" : "=r" (result) :: "memory"); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Priority Mask (non-secure) \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. \return Priority Mask value */ __STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) { uint32_t result; __ASM volatile ("MRS %0, primask_ns" : "=r" (result) :: "memory"); return(result); } #endif /** \brief Set Priority Mask \details Assigns the given value to the Priority Mask Register. \param [in] priMask Priority Mask */ __STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) { __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Priority Mask (non-secure) \details Assigns the given value to the non-secure Priority Mask Register when in secure state. \param [in] priMask Priority Mask */ __STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) { __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); } #endif #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) /** \brief Enable FIQ \details Enables FIQ interrupts by clearing the F-bit in the CPSR. Can only be executed in Privileged modes. */ __STATIC_FORCEINLINE void __enable_fault_irq(void) { __ASM volatile ("cpsie f" : : : "memory"); } /** \brief Disable FIQ \details Disables FIQ interrupts by setting the F-bit in the CPSR. Can only be executed in Privileged modes. */ __STATIC_FORCEINLINE void __disable_fault_irq(void) { __ASM volatile ("cpsid f" : : : "memory"); } /** \brief Get Base Priority \details Returns the current value of the Base Priority register. \return Base Priority register value */ __STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) { uint32_t result; __ASM volatile ("MRS %0, basepri" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Base Priority (non-secure) \details Returns the current value of the non-secure Base Priority register when in secure state. \return Base Priority register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) { uint32_t result; __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Base Priority \details Assigns the given value to the Base Priority register. \param [in] basePri Base Priority value to set */ __STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) { __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Base Priority (non-secure) \details Assigns the given value to the non-secure Base Priority register when in secure state. \param [in] basePri Base Priority value to set */ __STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) { __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); } #endif /** \brief Set Base Priority with condition \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, or the new value increases the BASEPRI priority level. \param [in] basePri Base Priority value to set */ __STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) { __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); } /** \brief Get Fault Mask \details Returns the current value of the Fault Mask register. \return Fault Mask register value */ __STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) { uint32_t result; __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Fault Mask (non-secure) \details Returns the current value of the non-secure Fault Mask register when in secure state. \return Fault Mask register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) { uint32_t result; __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Fault Mask \details Assigns the given value to the Fault Mask register. \param [in] faultMask Fault Mask value to set */ __STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) { __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Fault Mask (non-secure) \details Assigns the given value to the non-secure Fault Mask register when in secure state. \param [in] faultMask Fault Mask value to set */ __STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) { __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); } #endif #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) /** \brief Get Process Stack Pointer Limit Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence zero is returned always in non-secure mode. \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). \return PSPLIM Register value */ __STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure PSPLIM is RAZ/WI return 0U; #else uint32_t result; __ASM volatile ("MRS %0, psplim" : "=r" (result) ); return result; #endif } #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Process Stack Pointer Limit (non-secure) Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence zero is returned always. \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. \return PSPLIM Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) // without main extensions, the non-secure PSPLIM is RAZ/WI return 0U; #else uint32_t result; __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); return result; #endif } #endif /** \brief Set Process Stack Pointer Limit Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence the write is silently ignored in non-secure mode. \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set */ __STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure PSPLIM is RAZ/WI (void)ProcStackPtrLimit; #else __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); #endif } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Process Stack Pointer (non-secure) Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence the write is silently ignored. \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set */ __STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) // without main extensions, the non-secure PSPLIM is RAZ/WI (void)ProcStackPtrLimit; #else __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); #endif } #endif /** \brief Get Main Stack Pointer Limit Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence zero is returned always in non-secure mode. \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). \return MSPLIM Register value */ __STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure MSPLIM is RAZ/WI return 0U; #else uint32_t result; __ASM volatile ("MRS %0, msplim" : "=r" (result) ); return result; #endif } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Main Stack Pointer Limit (non-secure) Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence zero is returned always. \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. \return MSPLIM Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) // without main extensions, the non-secure MSPLIM is RAZ/WI return 0U; #else uint32_t result; __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); return result; #endif } #endif /** \brief Set Main Stack Pointer Limit Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence the write is silently ignored in non-secure mode. \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set */ __STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure MSPLIM is RAZ/WI (void)MainStackPtrLimit; #else __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); #endif } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Main Stack Pointer Limit (non-secure) Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence the write is silently ignored. \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. \param [in] MainStackPtrLimit Main Stack Pointer value to set */ __STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) // without main extensions, the non-secure MSPLIM is RAZ/WI (void)MainStackPtrLimit; #else __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); #endif } #endif #endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ /** \brief Get FPSCR \details Returns the current value of the Floating Point Status/Control register. \return Floating Point Status/Control register value */ __STATIC_FORCEINLINE uint32_t __get_FPSCR(void) { #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) #if __has_builtin(__builtin_arm_get_fpscr) // Re-enable using built-in when GCC has been fixed // || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ return __builtin_arm_get_fpscr(); #else uint32_t result; __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); return(result); #endif #else return(0U); #endif } /** \brief Set FPSCR \details Assigns the given value to the Floating Point Status/Control register. \param [in] fpscr Floating Point Status/Control value to set */ __STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) { #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) #if __has_builtin(__builtin_arm_set_fpscr) // Re-enable using built-in when GCC has been fixed // || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ __builtin_arm_set_fpscr(fpscr); #else __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); #endif #else (void)fpscr; #endif } /*@} end of CMSIS_Core_RegAccFunctions */ /* ########################## Core Instruction Access ######################### */ /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface Access to dedicated instructions @{ */ /* Define macros for porting to both thumb1 and thumb2. * For thumb1, use low register (r0-r7), specified by constraint "l" * Otherwise, use general registers, specified by constraint "r" */ #if defined (__thumb__) && !defined (__thumb2__) #define __CMSIS_GCC_OUT_REG(r) "=l" (r) #define __CMSIS_GCC_RW_REG(r) "+l" (r) #define __CMSIS_GCC_USE_REG(r) "l" (r) #else #define __CMSIS_GCC_OUT_REG(r) "=r" (r) #define __CMSIS_GCC_RW_REG(r) "+r" (r) #define __CMSIS_GCC_USE_REG(r) "r" (r) #endif /** \brief No Operation \details No Operation does nothing. This instruction can be used for code alignment purposes. */ #define __NOP() __ASM volatile ("nop") /** \brief Wait For Interrupt \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. */ #define __WFI() __ASM volatile ("wfi") /** \brief Wait For Event \details Wait For Event is a hint instruction that permits the processor to enter a low-power state until one of a number of events occurs. */ #define __WFE() __ASM volatile ("wfe") /** \brief Send Event \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. */ #define __SEV() __ASM volatile ("sev") /** \brief Instruction Synchronization Barrier \details Instruction Synchronization Barrier flushes the pipeline in the processor, so that all instructions following the ISB are fetched from cache or memory, after the instruction has been completed. */ __STATIC_FORCEINLINE void __ISB(void) { __ASM volatile ("isb 0xF":::"memory"); } /** \brief Data Synchronization Barrier \details Acts as a special kind of Data Memory Barrier. It completes when all explicit memory accesses before this instruction complete. */ __STATIC_FORCEINLINE void __DSB(void) { __ASM volatile ("dsb 0xF":::"memory"); } /** \brief Data Memory Barrier \details Ensures the apparent order of the explicit memory operations before and after the instruction, without ensuring their completion. */ __STATIC_FORCEINLINE void __DMB(void) { __ASM volatile ("dmb 0xF":::"memory"); } /** \brief Reverse byte order (32 bit) \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. \param [in] value Value to reverse \return Reversed value */ __STATIC_FORCEINLINE uint32_t __REV(uint32_t value) { #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) return __builtin_bswap32(value); #else uint32_t result; __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); return result; #endif } /** \brief Reverse byte order (16 bit) \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. \param [in] value Value to reverse \return Reversed value */ __STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) { uint32_t result; __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); return result; } /** \brief Reverse byte order (16 bit) \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. \param [in] value Value to reverse \return Reversed value */ __STATIC_FORCEINLINE int16_t __REVSH(int16_t value) { #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) return (int16_t)__builtin_bswap16(value); #else int16_t result; __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); return result; #endif } /** \brief Rotate Right in unsigned value (32 bit) \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. \param [in] op1 Value to rotate \param [in] op2 Number of Bits to rotate \return Rotated value */ __STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) { op2 %= 32U; if (op2 == 0U) { return op1; } return (op1 >> op2) | (op1 << (32U - op2)); } /** \brief Breakpoint \details Causes the processor to enter Debug state. Debug tools can use this to investigate system state when the instruction at a particular address is reached. \param [in] value is ignored by the processor. If required, a debugger can use it to store additional information about the breakpoint. */ #define __BKPT(value) __ASM volatile ("bkpt "#value) /** \brief Reverse bit order of value \details Reverses the bit order of the given value. \param [in] value Value to reverse \return Reversed value */ __STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) { uint32_t result; #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); #else uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ result = value; /* r will be reversed bits of v; first get LSB of v */ for (value >>= 1U; value != 0U; value >>= 1U) { result <<= 1U; result |= value & 1U; s--; } result <<= s; /* shift when v's highest bits are zero */ #endif return result; } /** \brief Count leading zeros \details Counts the number of leading zeros of a data value. \param [in] value Value to count the leading zeros \return number of leading zeros in value */ __STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) { /* Even though __builtin_clz produces a CLZ instruction on ARM, formally __builtin_clz(0) is undefined behaviour, so handle this case specially. This guarantees ARM-compatible results if happening to compile on a non-ARM target, and ensures the compiler doesn't decide to activate any optimisations using the logic "value was passed to __builtin_clz, so it is non-zero". ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a single CLZ instruction. */ if (value == 0U) { return 32U; } return __builtin_clz(value); } #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) /** \brief LDR Exclusive (8 bit) \details Executes a exclusive LDR instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ __STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) { uint32_t result; #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); #else /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not accepted by assembler. So has to use following less efficient pattern. */ __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); #endif return ((uint8_t) result); /* Add explicit type cast here */ } /** \brief LDR Exclusive (16 bit) \details Executes a exclusive LDR instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ __STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) { uint32_t result; #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); #else /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not accepted by assembler. So has to use following less efficient pattern. */ __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); #endif return ((uint16_t) result); /* Add explicit type cast here */ } /** \brief LDR Exclusive (32 bit) \details Executes a exclusive LDR instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ __STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) { uint32_t result; __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); return(result); } /** \brief STR Exclusive (8 bit) \details Executes a exclusive STR instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ __STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) { uint32_t result; __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); return(result); } /** \brief STR Exclusive (16 bit) \details Executes a exclusive STR instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ __STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) { uint32_t result; __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); return(result); } /** \brief STR Exclusive (32 bit) \details Executes a exclusive STR instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ __STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) { uint32_t result; __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); return(result); } /** \brief Remove the exclusive lock \details Removes the exclusive lock which is created by LDREX. */ __STATIC_FORCEINLINE void __CLREX(void) { __ASM volatile ("clrex" ::: "memory"); } #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) /** \brief Signed Saturate \details Saturates a signed value. \param [in] ARG1 Value to be saturated \param [in] ARG2 Bit position to saturate to (1..32) \return Saturated value */ #define __SSAT(ARG1,ARG2) \ __extension__ \ ({ \ int32_t __RES, __ARG1 = (ARG1); \ __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ __RES; \ }) /** \brief Unsigned Saturate \details Saturates an unsigned value. \param [in] ARG1 Value to be saturated \param [in] ARG2 Bit position to saturate to (0..31) \return Saturated value */ #define __USAT(ARG1,ARG2) \ __extension__ \ ({ \ uint32_t __RES, __ARG1 = (ARG1); \ __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ __RES; \ }) /** \brief Rotate Right with Extend (32 bit) \details Moves each bit of a bitstring right by one bit. The carry input is shifted in at the left end of the bitstring. \param [in] value Value to rotate \return Rotated value */ __STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) { uint32_t result; __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); return(result); } /** \brief LDRT Unprivileged (8 bit) \details Executes a Unprivileged LDRT instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ __STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) { uint32_t result; #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); #else /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not accepted by assembler. So has to use following less efficient pattern. */ __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); #endif return ((uint8_t) result); /* Add explicit type cast here */ } /** \brief LDRT Unprivileged (16 bit) \details Executes a Unprivileged LDRT instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ __STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) { uint32_t result; #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); #else /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not accepted by assembler. So has to use following less efficient pattern. */ __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); #endif return ((uint16_t) result); /* Add explicit type cast here */ } /** \brief LDRT Unprivileged (32 bit) \details Executes a Unprivileged LDRT instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ __STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) { uint32_t result; __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); return(result); } /** \brief STRT Unprivileged (8 bit) \details Executes a Unprivileged STRT instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) { __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief STRT Unprivileged (16 bit) \details Executes a Unprivileged STRT instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) { __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief STRT Unprivileged (32 bit) \details Executes a Unprivileged STRT instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) { __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); } #else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ /** \brief Signed Saturate \details Saturates a signed value. \param [in] value Value to be saturated \param [in] sat Bit position to saturate to (1..32) \return Saturated value */ __STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) { if ((sat >= 1U) && (sat <= 32U)) { const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); const int32_t min = -1 - max ; if (val > max) { return max; } else if (val < min) { return min; } } return val; } /** \brief Unsigned Saturate \details Saturates an unsigned value. \param [in] value Value to be saturated \param [in] sat Bit position to saturate to (0..31) \return Saturated value */ __STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) { if (sat <= 31U) { const uint32_t max = ((1U << sat) - 1U); if (val > (int32_t)max) { return max; } else if (val < 0) { return 0U; } } return (uint32_t)val; } #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) /** \brief Load-Acquire (8 bit) \details Executes a LDAB instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ __STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) { uint32_t result; __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); return ((uint8_t) result); } /** \brief Load-Acquire (16 bit) \details Executes a LDAH instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ __STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) { uint32_t result; __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); return ((uint16_t) result); } /** \brief Load-Acquire (32 bit) \details Executes a LDA instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ __STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) { uint32_t result; __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); return(result); } /** \brief Store-Release (8 bit) \details Executes a STLB instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) { __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief Store-Release (16 bit) \details Executes a STLH instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) { __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief Store-Release (32 bit) \details Executes a STL instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) { __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief Load-Acquire Exclusive (8 bit) \details Executes a LDAB exclusive instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ __STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) { uint32_t result; __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) ); return ((uint8_t) result); } /** \brief Load-Acquire Exclusive (16 bit) \details Executes a LDAH exclusive instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ __STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) { uint32_t result; __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) ); return ((uint16_t) result); } /** \brief Load-Acquire Exclusive (32 bit) \details Executes a LDA exclusive instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ __STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) { uint32_t result; __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) ); return(result); } /** \brief Store-Release Exclusive (8 bit) \details Executes a STLB exclusive instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ __STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) { uint32_t result; __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); return(result); } /** \brief Store-Release Exclusive (16 bit) \details Executes a STLH exclusive instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ __STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) { uint32_t result; __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); return(result); } /** \brief Store-Release Exclusive (32 bit) \details Executes a STL exclusive instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ __STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) { uint32_t result; __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); return(result); } #endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ /*@}*/ /* end of group CMSIS_Core_InstructionInterface */ /* ################### Compiler specific Intrinsics ########################### */ /** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics Access to dedicated SIMD instructions @{ */ #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) __STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); return(result); } #define __SSAT16(ARG1,ARG2) \ ({ \ int32_t __RES, __ARG1 = (ARG1); \ __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ __RES; \ }) #define __USAT16(ARG1,ARG2) \ ({ \ uint32_t __RES, __ARG1 = (ARG1); \ __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ __RES; \ }) __STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) { uint32_t result; __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); return(result); } __STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) { uint32_t result; __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); return(result); } __STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); return(result); } __STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; uint64_t w64; } llr; llr.w64 = acc; #ifndef __ARMEB__ /* Little endian */ __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); #else /* Big endian */ __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); #endif return(llr.w64); } __STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; uint64_t w64; } llr; llr.w64 = acc; #ifndef __ARMEB__ /* Little endian */ __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); #else /* Big endian */ __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); #endif return(llr.w64); } __STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); return(result); } __STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; uint64_t w64; } llr; llr.w64 = acc; #ifndef __ARMEB__ /* Little endian */ __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); #else /* Big endian */ __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); #endif return(llr.w64); } __STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; uint64_t w64; } llr; llr.w64 = acc; #ifndef __ARMEB__ /* Little endian */ __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); #else /* Big endian */ __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); #endif return(llr.w64); } __STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) { int32_t result; __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) { int32_t result; __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } #if 0 #define __PKHBT(ARG1,ARG2,ARG3) \ ({ \ uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ __RES; \ }) #define __PKHTB(ARG1,ARG2,ARG3) \ ({ \ uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ if (ARG3 == 0) \ __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ else \ __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ __RES; \ }) #endif #define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) #define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) __STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) { int32_t result; __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); return(result); } #endif /* (__ARM_FEATURE_DSP == 1) */ /*@} end of group CMSIS_SIMD_intrinsics */ #pragma GCC diagnostic pop #endif /* __CMSIS_GCC_H */ ================================================ FILE: 3rd_party/CMSIS/Include/cmsis_iccarm.h ================================================ /**************************************************************************//** * @file cmsis_iccarm.h * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file * @version V5.1.0 * @date 08. May 2019 ******************************************************************************/ //------------------------------------------------------------------------------ // // Copyright (c) 2017-2019 IAR Systems // Copyright (c) 2017-2019 Arm Limited. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License") // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //------------------------------------------------------------------------------ #ifndef __CMSIS_ICCARM_H__ #define __CMSIS_ICCARM_H__ #ifndef __ICCARM__ #error This file should only be compiled by ICCARM #endif #pragma system_include #define __IAR_FT _Pragma("inline=forced") __intrinsic #if (__VER__ >= 8000000) #define __ICCARM_V8 1 #else #define __ICCARM_V8 0 #endif #ifndef __ALIGNED #if __ICCARM_V8 #define __ALIGNED(x) __attribute__((aligned(x))) #elif (__VER__ >= 7080000) /* Needs IAR language extensions */ #define __ALIGNED(x) __attribute__((aligned(x))) #else #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. #define __ALIGNED(x) #endif #endif /* Define compiler macros for CPU architecture, used in CMSIS 5. */ #if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ /* Macros already defined */ #else #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) #define __ARM_ARCH_8M_MAIN__ 1 #elif defined(__ARM8M_BASELINE__) #define __ARM_ARCH_8M_BASE__ 1 #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' #if __ARM_ARCH == 6 #define __ARM_ARCH_6M__ 1 #elif __ARM_ARCH == 7 #if __ARM_FEATURE_DSP #define __ARM_ARCH_7EM__ 1 #else #define __ARM_ARCH_7M__ 1 #endif #endif /* __ARM_ARCH */ #endif /* __ARM_ARCH_PROFILE == 'M' */ #endif /* Alternativ core deduction for older ICCARM's */ #if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) #define __ARM_ARCH_6M__ 1 #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) #define __ARM_ARCH_7M__ 1 #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) #define __ARM_ARCH_7EM__ 1 #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) #define __ARM_ARCH_8M_BASE__ 1 #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) #define __ARM_ARCH_8M_MAIN__ 1 #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) #define __ARM_ARCH_8M_MAIN__ 1 #else #error "Unknown target." #endif #endif #if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 #define __IAR_M0_FAMILY 1 #elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 #define __IAR_M0_FAMILY 1 #else #define __IAR_M0_FAMILY 0 #endif #ifndef __ASM #define __ASM __asm #endif #ifndef __COMPILER_BARRIER #define __COMPILER_BARRIER() __ASM volatile("":::"memory") #endif #ifndef __INLINE #define __INLINE inline #endif #ifndef __NO_RETURN #if __ICCARM_V8 #define __NO_RETURN __attribute__((__noreturn__)) #else #define __NO_RETURN _Pragma("object_attribute=__noreturn") #endif #endif #ifndef __PACKED #if __ICCARM_V8 #define __PACKED __attribute__((packed, aligned(1))) #else /* Needs IAR language extensions */ #define __PACKED __packed #endif #endif #ifndef __PACKED_STRUCT #if __ICCARM_V8 #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) #else /* Needs IAR language extensions */ #define __PACKED_STRUCT __packed struct #endif #endif #ifndef __PACKED_UNION #if __ICCARM_V8 #define __PACKED_UNION union __attribute__((packed, aligned(1))) #else /* Needs IAR language extensions */ #define __PACKED_UNION __packed union #endif #endif #ifndef __RESTRICT #if __ICCARM_V8 #define __RESTRICT __restrict #else /* Needs IAR language extensions */ #define __RESTRICT restrict #endif #endif #ifndef __STATIC_INLINE #define __STATIC_INLINE static inline #endif #ifndef __FORCEINLINE #define __FORCEINLINE _Pragma("inline=forced") #endif #ifndef __STATIC_FORCEINLINE #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE #endif #ifndef __UNALIGNED_UINT16_READ #pragma language=save #pragma language=extended __IAR_FT uint16_t __iar_uint16_read(void const *ptr) { return *(__packed uint16_t*)(ptr); } #pragma language=restore #define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) #endif #ifndef __UNALIGNED_UINT16_WRITE #pragma language=save #pragma language=extended __IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) { *(__packed uint16_t*)(ptr) = val;; } #pragma language=restore #define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) #endif #ifndef __UNALIGNED_UINT32_READ #pragma language=save #pragma language=extended __IAR_FT uint32_t __iar_uint32_read(void const *ptr) { return *(__packed uint32_t*)(ptr); } #pragma language=restore #define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) #endif #ifndef __UNALIGNED_UINT32_WRITE #pragma language=save #pragma language=extended __IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) { *(__packed uint32_t*)(ptr) = val;; } #pragma language=restore #define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) #endif #ifndef __UNALIGNED_UINT32 /* deprecated */ #pragma language=save #pragma language=extended __packed struct __iar_u32 { uint32_t v; }; #pragma language=restore #define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) #endif #ifndef __USED #if __ICCARM_V8 #define __USED __attribute__((used)) #else #define __USED _Pragma("__root") #endif #endif #ifndef __WEAK #if __ICCARM_V8 #define __WEAK __attribute__((weak)) #else #define __WEAK _Pragma("__weak") #endif #endif #ifndef __PROGRAM_START #define __PROGRAM_START __iar_program_start #endif #ifndef __INITIAL_SP #define __INITIAL_SP CSTACK$$Limit #endif #ifndef __STACK_LIMIT #define __STACK_LIMIT CSTACK$$Base #endif #ifndef __VECTOR_TABLE #define __VECTOR_TABLE __vector_table #endif #ifndef __VECTOR_TABLE_ATTRIBUTE #define __VECTOR_TABLE_ATTRIBUTE @".intvec" #endif #ifndef __ICCARM_INTRINSICS_VERSION__ #define __ICCARM_INTRINSICS_VERSION__ 0 #endif #if __ICCARM_INTRINSICS_VERSION__ == 2 #if defined(__CLZ) #undef __CLZ #endif #if defined(__REVSH) #undef __REVSH #endif #if defined(__RBIT) #undef __RBIT #endif #if defined(__SSAT) #undef __SSAT #endif #if defined(__USAT) #undef __USAT #endif #include "iccarm_builtin.h" #define __disable_fault_irq __iar_builtin_disable_fiq #define __disable_irq __iar_builtin_disable_interrupt #define __enable_fault_irq __iar_builtin_enable_fiq #define __enable_irq __iar_builtin_enable_interrupt #define __arm_rsr __iar_builtin_rsr #define __arm_wsr __iar_builtin_wsr #define __get_APSR() (__arm_rsr("APSR")) #define __get_BASEPRI() (__arm_rsr("BASEPRI")) #define __get_CONTROL() (__arm_rsr("CONTROL")) #define __get_FAULTMASK() (__arm_rsr("FAULTMASK")) #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) #define __get_FPSCR() (__arm_rsr("FPSCR")) #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE))) #else #define __get_FPSCR() ( 0 ) #define __set_FPSCR(VALUE) ((void)VALUE) #endif #define __get_IPSR() (__arm_rsr("IPSR")) #define __get_MSP() (__arm_rsr("MSP")) #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure MSPLIM is RAZ/WI #define __get_MSPLIM() (0U) #else #define __get_MSPLIM() (__arm_rsr("MSPLIM")) #endif #define __get_PRIMASK() (__arm_rsr("PRIMASK")) #define __get_PSP() (__arm_rsr("PSP")) #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure PSPLIM is RAZ/WI #define __get_PSPLIM() (0U) #else #define __get_PSPLIM() (__arm_rsr("PSPLIM")) #endif #define __get_xPSR() (__arm_rsr("xPSR")) #define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE))) #define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE))) #define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE))) #define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE))) #define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE))) #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure MSPLIM is RAZ/WI #define __set_MSPLIM(VALUE) ((void)(VALUE)) #else #define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE))) #endif #define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE))) #define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE))) #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure PSPLIM is RAZ/WI #define __set_PSPLIM(VALUE) ((void)(VALUE)) #else #define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE))) #endif #define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS")) #define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE))) #define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS")) #define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE))) #define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS")) #define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE))) #define __TZ_get_SP_NS() (__arm_rsr("SP_NS")) #define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE))) #define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS")) #define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE))) #define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS")) #define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE))) #define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS")) #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure PSPLIM is RAZ/WI #define __TZ_get_PSPLIM_NS() (0U) #define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE)) #else #define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS")) #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) #endif #define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS")) #define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE))) #define __NOP __iar_builtin_no_operation #define __CLZ __iar_builtin_CLZ #define __CLREX __iar_builtin_CLREX #define __DMB __iar_builtin_DMB #define __DSB __iar_builtin_DSB #define __ISB __iar_builtin_ISB #define __LDREXB __iar_builtin_LDREXB #define __LDREXH __iar_builtin_LDREXH #define __LDREXW __iar_builtin_LDREX #define __RBIT __iar_builtin_RBIT #define __REV __iar_builtin_REV #define __REV16 __iar_builtin_REV16 __IAR_FT int16_t __REVSH(int16_t val) { return (int16_t) __iar_builtin_REVSH(val); } #define __ROR __iar_builtin_ROR #define __RRX __iar_builtin_RRX #define __SEV __iar_builtin_SEV #if !__IAR_M0_FAMILY #define __SSAT __iar_builtin_SSAT #endif #define __STREXB __iar_builtin_STREXB #define __STREXH __iar_builtin_STREXH #define __STREXW __iar_builtin_STREX #if !__IAR_M0_FAMILY #define __USAT __iar_builtin_USAT #endif #define __WFE __iar_builtin_WFE #define __WFI __iar_builtin_WFI #if __ARM_MEDIA__ #define __SADD8 __iar_builtin_SADD8 #define __QADD8 __iar_builtin_QADD8 #define __SHADD8 __iar_builtin_SHADD8 #define __UADD8 __iar_builtin_UADD8 #define __UQADD8 __iar_builtin_UQADD8 #define __UHADD8 __iar_builtin_UHADD8 #define __SSUB8 __iar_builtin_SSUB8 #define __QSUB8 __iar_builtin_QSUB8 #define __SHSUB8 __iar_builtin_SHSUB8 #define __USUB8 __iar_builtin_USUB8 #define __UQSUB8 __iar_builtin_UQSUB8 #define __UHSUB8 __iar_builtin_UHSUB8 #define __SADD16 __iar_builtin_SADD16 #define __QADD16 __iar_builtin_QADD16 #define __SHADD16 __iar_builtin_SHADD16 #define __UADD16 __iar_builtin_UADD16 #define __UQADD16 __iar_builtin_UQADD16 #define __UHADD16 __iar_builtin_UHADD16 #define __SSUB16 __iar_builtin_SSUB16 #define __QSUB16 __iar_builtin_QSUB16 #define __SHSUB16 __iar_builtin_SHSUB16 #define __USUB16 __iar_builtin_USUB16 #define __UQSUB16 __iar_builtin_UQSUB16 #define __UHSUB16 __iar_builtin_UHSUB16 #define __SASX __iar_builtin_SASX #define __QASX __iar_builtin_QASX #define __SHASX __iar_builtin_SHASX #define __UASX __iar_builtin_UASX #define __UQASX __iar_builtin_UQASX #define __UHASX __iar_builtin_UHASX #define __SSAX __iar_builtin_SSAX #define __QSAX __iar_builtin_QSAX #define __SHSAX __iar_builtin_SHSAX #define __USAX __iar_builtin_USAX #define __UQSAX __iar_builtin_UQSAX #define __UHSAX __iar_builtin_UHSAX #define __USAD8 __iar_builtin_USAD8 #define __USADA8 __iar_builtin_USADA8 #define __SSAT16 __iar_builtin_SSAT16 #define __USAT16 __iar_builtin_USAT16 #define __UXTB16 __iar_builtin_UXTB16 #define __UXTAB16 __iar_builtin_UXTAB16 #define __SXTB16 __iar_builtin_SXTB16 #define __SXTAB16 __iar_builtin_SXTAB16 #define __SMUAD __iar_builtin_SMUAD #define __SMUADX __iar_builtin_SMUADX #define __SMMLA __iar_builtin_SMMLA #define __SMLAD __iar_builtin_SMLAD #define __SMLADX __iar_builtin_SMLADX #define __SMLALD __iar_builtin_SMLALD #define __SMLALDX __iar_builtin_SMLALDX #define __SMUSD __iar_builtin_SMUSD #define __SMUSDX __iar_builtin_SMUSDX #define __SMLSD __iar_builtin_SMLSD #define __SMLSDX __iar_builtin_SMLSDX #define __SMLSLD __iar_builtin_SMLSLD #define __SMLSLDX __iar_builtin_SMLSLDX #define __SEL __iar_builtin_SEL #define __QADD __iar_builtin_QADD #define __QSUB __iar_builtin_QSUB #define __PKHBT __iar_builtin_PKHBT #define __PKHTB __iar_builtin_PKHTB #endif #else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ #if __IAR_M0_FAMILY /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ #define __CLZ __cmsis_iar_clz_not_active #define __SSAT __cmsis_iar_ssat_not_active #define __USAT __cmsis_iar_usat_not_active #define __RBIT __cmsis_iar_rbit_not_active #define __get_APSR __cmsis_iar_get_APSR_not_active #endif #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) #define __get_FPSCR __cmsis_iar_get_FPSR_not_active #define __set_FPSCR __cmsis_iar_set_FPSR_not_active #endif #ifdef __INTRINSICS_INCLUDED #error intrinsics.h is already included previously! #endif #include #if __IAR_M0_FAMILY /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ #undef __CLZ #undef __SSAT #undef __USAT #undef __RBIT #undef __get_APSR __STATIC_INLINE uint8_t __CLZ(uint32_t data) { if (data == 0U) { return 32U; } uint32_t count = 0U; uint32_t mask = 0x80000000U; while ((data & mask) == 0U) { count += 1U; mask = mask >> 1U; } return count; } __STATIC_INLINE uint32_t __RBIT(uint32_t v) { uint8_t sc = 31U; uint32_t r = v; for (v >>= 1U; v; v >>= 1U) { r <<= 1U; r |= v & 1U; sc--; } return (r << sc); } __STATIC_INLINE uint32_t __get_APSR(void) { uint32_t res; __asm("MRS %0,APSR" : "=r" (res)); return res; } #endif #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) #undef __get_FPSCR #undef __set_FPSCR #define __get_FPSCR() (0) #define __set_FPSCR(VALUE) ((void)VALUE) #endif #pragma diag_suppress=Pe940 #pragma diag_suppress=Pe177 #define __enable_irq __enable_interrupt #define __disable_irq __disable_interrupt #define __NOP __no_operation #define __get_xPSR __get_PSR #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) { return __LDREX((unsigned long *)ptr); } __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) { return __STREX(value, (unsigned long *)ptr); } #endif /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ #if (__CORTEX_M >= 0x03) __IAR_FT uint32_t __RRX(uint32_t value) { uint32_t result; __ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); return(result); } __IAR_FT void __set_BASEPRI_MAX(uint32_t value) { __asm volatile("MSR BASEPRI_MAX,%0"::"r" (value)); } #define __enable_fault_irq __enable_fiq #define __disable_fault_irq __disable_fiq #endif /* (__CORTEX_M >= 0x03) */ __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) { return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); } #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) __IAR_FT uint32_t __get_MSPLIM(void) { uint32_t res; #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure MSPLIM is RAZ/WI res = 0U; #else __asm volatile("MRS %0,MSPLIM" : "=r" (res)); #endif return res; } __IAR_FT void __set_MSPLIM(uint32_t value) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure MSPLIM is RAZ/WI (void)value; #else __asm volatile("MSR MSPLIM,%0" :: "r" (value)); #endif } __IAR_FT uint32_t __get_PSPLIM(void) { uint32_t res; #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure PSPLIM is RAZ/WI res = 0U; #else __asm volatile("MRS %0,PSPLIM" : "=r" (res)); #endif return res; } __IAR_FT void __set_PSPLIM(uint32_t value) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure PSPLIM is RAZ/WI (void)value; #else __asm volatile("MSR PSPLIM,%0" :: "r" (value)); #endif } __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) { uint32_t res; __asm volatile("MRS %0,CONTROL_NS" : "=r" (res)); return res; } __IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) { __asm volatile("MSR CONTROL_NS,%0" :: "r" (value)); } __IAR_FT uint32_t __TZ_get_PSP_NS(void) { uint32_t res; __asm volatile("MRS %0,PSP_NS" : "=r" (res)); return res; } __IAR_FT void __TZ_set_PSP_NS(uint32_t value) { __asm volatile("MSR PSP_NS,%0" :: "r" (value)); } __IAR_FT uint32_t __TZ_get_MSP_NS(void) { uint32_t res; __asm volatile("MRS %0,MSP_NS" : "=r" (res)); return res; } __IAR_FT void __TZ_set_MSP_NS(uint32_t value) { __asm volatile("MSR MSP_NS,%0" :: "r" (value)); } __IAR_FT uint32_t __TZ_get_SP_NS(void) { uint32_t res; __asm volatile("MRS %0,SP_NS" : "=r" (res)); return res; } __IAR_FT void __TZ_set_SP_NS(uint32_t value) { __asm volatile("MSR SP_NS,%0" :: "r" (value)); } __IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) { uint32_t res; __asm volatile("MRS %0,PRIMASK_NS" : "=r" (res)); return res; } __IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) { __asm volatile("MSR PRIMASK_NS,%0" :: "r" (value)); } __IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) { uint32_t res; __asm volatile("MRS %0,BASEPRI_NS" : "=r" (res)); return res; } __IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) { __asm volatile("MSR BASEPRI_NS,%0" :: "r" (value)); } __IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) { uint32_t res; __asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res)); return res; } __IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) { __asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value)); } __IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) { uint32_t res; #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure PSPLIM is RAZ/WI res = 0U; #else __asm volatile("MRS %0,PSPLIM_NS" : "=r" (res)); #endif return res; } __IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure PSPLIM is RAZ/WI (void)value; #else __asm volatile("MSR PSPLIM_NS,%0" :: "r" (value)); #endif } __IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) { uint32_t res; __asm volatile("MRS %0,MSPLIM_NS" : "=r" (res)); return res; } __IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) { __asm volatile("MSR MSPLIM_NS,%0" :: "r" (value)); } #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ #endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ #define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) #if __IAR_M0_FAMILY __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) { if ((sat >= 1U) && (sat <= 32U)) { const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); const int32_t min = -1 - max ; if (val > max) { return max; } else if (val < min) { return min; } } return val; } __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) { if (sat <= 31U) { const uint32_t max = ((1U << sat) - 1U); if (val > (int32_t)max) { return max; } else if (val < 0) { return 0U; } } return (uint32_t)val; } #endif #if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) { uint32_t res; __ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); return ((uint8_t)res); } __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) { uint32_t res; __ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); return ((uint16_t)res); } __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) { uint32_t res; __ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); return res; } __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) { __ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); } __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) { __ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); } __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) { __ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); } #endif /* (__CORTEX_M >= 0x03) */ #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) { uint32_t res; __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); return ((uint8_t)res); } __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) { uint32_t res; __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); return ((uint16_t)res); } __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) { uint32_t res; __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); return res; } __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) { __ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); } __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) { __ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); } __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) { __ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); } __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) { uint32_t res; __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); return ((uint8_t)res); } __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) { uint32_t res; __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); return ((uint16_t)res); } __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) { uint32_t res; __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); return res; } __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) { uint32_t res; __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); return res; } __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) { uint32_t res; __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); return res; } __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) { uint32_t res; __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); return res; } #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ #undef __IAR_FT #undef __IAR_M0_FAMILY #undef __ICCARM_V8 #pragma diag_default=Pe940 #pragma diag_default=Pe177 #endif /* __CMSIS_ICCARM_H__ */ ================================================ FILE: 3rd_party/CMSIS/Include/cmsis_version.h ================================================ /**************************************************************************//** * @file cmsis_version.h * @brief CMSIS Core(M) Version definitions * @version V5.0.3 * @date 24. June 2019 ******************************************************************************/ /* * Copyright (c) 2009-2019 ARM Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CMSIS_VERSION_H #define __CMSIS_VERSION_H /* CMSIS Version definitions */ #define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ #define __CM_CMSIS_VERSION_SUB ( 3U) /*!< [15:0] CMSIS Core(M) sub version */ #define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ #endif ================================================ FILE: 3rd_party/CMSIS/Include/core_armv81mml.h ================================================ /**************************************************************************//** * @file core_armv81mml.h * @brief CMSIS Armv8.1-M Mainline Core Peripheral Access Layer Header File * @version V1.0.0 * @date 15. March 2019 ******************************************************************************/ /* * Copyright (c) 2018-2019 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_ARMV81MML_H_GENERIC #define __CORE_ARMV81MML_H_GENERIC #include #ifdef __cplusplus extern "C" { #endif /** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions CMSIS violates the following MISRA-C:2004 rules: \li Required Rule 8.5, object/function definition in header file.
Function definitions in header files are used to allow 'inlining'. \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
Unions are used for effective representation of core registers. \li Advisory Rule 19.7, Function-like macro defined.
Function-like macros are used to allow more efficient code. */ /******************************************************************************* * CMSIS definitions ******************************************************************************/ /** \ingroup Cortex_ARMV81MML @{ */ #include "cmsis_version.h" #define __ARM_ARCH_8M_MAIN__ 1 // patching for now /* CMSIS ARMV81MML definitions */ #define __ARMv81MML_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ #define __ARMv81MML_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __ARMv81MML_CMSIS_VERSION ((__ARMv81MML_CMSIS_VERSION_MAIN << 16U) | \ __ARMv81MML_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (81U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. */ #if defined ( __CC_ARM ) #if defined __TARGET_FPU_VFP #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined(__ARM_FEATURE_DSP) #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined __ARM_FP #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined(__ARM_FEATURE_DSP) #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined(__ARM_FEATURE_DSP) #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined(__ARM_FEATURE_DSP) #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __TASKING__ ) #if defined __FPU_VFP__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __CSMC__ ) #if ( __CSMC__ & 0x400U) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #endif #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ #ifdef __cplusplus } #endif #endif /* __CORE_ARMV81MML_H_GENERIC */ #ifndef __CMSIS_GENERIC #ifndef __CORE_ARMV81MML_H_DEPENDANT #define __CORE_ARMV81MML_H_DEPENDANT #ifdef __cplusplus extern "C" { #endif /* check device defines and use defaults */ #if defined __CHECK_DEVICE_DEFINES #ifndef __ARMv81MML_REV #define __ARMv81MML_REV 0x0000U #warning "__ARMv81MML_REV not defined in device header file; using default!" #endif #ifndef __FPU_PRESENT #define __FPU_PRESENT 0U #warning "__FPU_PRESENT not defined in device header file; using default!" #endif #ifndef __MPU_PRESENT #define __MPU_PRESENT 0U #warning "__MPU_PRESENT not defined in device header file; using default!" #endif #ifndef __SAUREGION_PRESENT #define __SAUREGION_PRESENT 0U #warning "__SAUREGION_PRESENT not defined in device header file; using default!" #endif #ifndef __DSP_PRESENT #define __DSP_PRESENT 0U #warning "__DSP_PRESENT not defined in device header file; using default!" #endif #ifndef __NVIC_PRIO_BITS #define __NVIC_PRIO_BITS 3U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif #ifndef __Vendor_SysTickConfig #define __Vendor_SysTickConfig 0U #warning "__Vendor_SysTickConfig not defined in device header file; using default!" #endif #endif /* IO definitions (access restrictions to peripheral registers) */ /** \defgroup CMSIS_glob_defs CMSIS Global Defines IO Type Qualifiers are used \li to specify the access to peripheral variables. \li for automatic generation of peripheral register debug information. */ #ifdef __cplusplus #define __I volatile /*!< Defines 'read only' permissions */ #else #define __I volatile const /*!< Defines 'read only' permissions */ #endif #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */ /* following defines should be used for structure members */ #define __IM volatile const /*! Defines 'read only' structure member permissions */ #define __OM volatile /*! Defines 'write only' structure member permissions */ #define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group ARMv81MML */ /******************************************************************************* * Register Abstraction Core Register contain: - Core Register - Core NVIC Register - Core SCB Register - Core SysTick Register - Core Debug Register - Core MPU Register - Core SAU Register - Core FPU Register ******************************************************************************/ /** \defgroup CMSIS_core_register Defines and Type Definitions \brief Type definitions and defines for Cortex-M processor based devices. */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CORE Status and Control Registers \brief Core Register type definitions. @{ */ /** \brief Union type to access the Application Program Status Register (APSR). */ typedef union { struct { uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } APSR_Type; /* APSR Register Definitions */ #define APSR_N_Pos 31U /*!< APSR: N Position */ #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ #define APSR_Z_Pos 30U /*!< APSR: Z Position */ #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ #define APSR_C_Pos 29U /*!< APSR: C Position */ #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ #define APSR_V_Pos 28U /*!< APSR: V Position */ #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ #define APSR_Q_Pos 27U /*!< APSR: Q Position */ #define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ #define APSR_GE_Pos 16U /*!< APSR: GE Position */ #define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ /** \brief Union type to access the Interrupt Program Status Register (IPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } IPSR_Type; /* IPSR Register Definitions */ #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ /** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } xPSR_Type; /* xPSR Register Definitions */ #define xPSR_N_Pos 31U /*!< xPSR: N Position */ #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ #define xPSR_C_Pos 29U /*!< xPSR: C Position */ #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ #define xPSR_V_Pos 28U /*!< xPSR: V Position */ #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ #define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ #define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ #define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ #define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ #define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ #define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ /** \brief Union type to access the Control Registers (CONTROL). */ typedef union { struct { uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } CONTROL_Type; /* CONTROL Register Definitions */ #define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ #define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ #define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ #define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ #define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ #define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ /*@} end of group CMSIS_CORE */ /** \ingroup CMSIS_core_register \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) \brief Type definitions for the NVIC Registers @{ */ /** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). */ typedef struct { __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[16U]; __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ uint32_t RSERVED1[16U]; __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[16U]; __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ uint32_t RESERVED3[16U]; __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ uint32_t RESERVED4[16U]; __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ uint32_t RESERVED5[16U]; __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ uint32_t RESERVED6[580U]; __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ } NVIC_Type; /* Software Triggered Interrupt Register Definitions */ #define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ #define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ /*@} end of group CMSIS_NVIC */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCB System Control Block (SCB) \brief Type definitions for the System Control Block Registers @{ */ /** \brief Structure type to access the System Control Block (SCB). */ typedef struct { __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ uint32_t RESERVED3[92U]; __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ uint32_t RESERVED4[15U]; __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ uint32_t RESERVED5[1U]; __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ uint32_t RESERVED6[1U]; __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ uint32_t RESERVED7[6U]; __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ uint32_t RESERVED8[1U]; __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ } SCB_Type; /* SCB CPUID Register Definitions */ #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ /* SCB Interrupt Control State Register Definitions */ #define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ #define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ #define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ #define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ #define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ #define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ #define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ #define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ #define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ #define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ /* SCB Vector Table Offset Register Definitions */ #define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ #define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ /* SCB Application Interrupt and Reset Control Register Definitions */ #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ #define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ #define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ #define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ #define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ #define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ #define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ #define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ #define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ /* SCB System Control Register Definitions */ #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ #define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ #define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ /* SCB Configuration Control Register Definitions */ #define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ #define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ #define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ #define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ #define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ #define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ #define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ #define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ #define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ #define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ #define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ #define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ #define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ #define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ /* SCB System Handler Control and State Register Definitions */ #define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ #define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ #define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ #define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ #define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ #define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ #define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ #define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ #define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ #define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ #define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ #define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ #define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ #define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ #define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ #define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ #define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ #define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ #define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ #define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ #define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ #define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ #define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ #define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ #define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ #define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ #define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ #define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ #define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ #define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ #define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ #define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ #define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ #define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ #define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ #define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ #define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ #define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ /* SCB Configurable Fault Status Register Definitions */ #define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ #define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ #define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ #define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ #define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ #define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ /* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ #define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ #define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ #define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ #define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ #define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ #define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ #define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ #define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ #define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ #define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ #define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ /* BusFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ #define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ #define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ #define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ #define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ #define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ #define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ #define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ #define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ #define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ #define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ #define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ #define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ #define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ /* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ #define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ #define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ #define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ #define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ #define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ #define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ #define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ #define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ #define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ #define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ #define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ #define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ #define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ /* SCB Hard Fault Status Register Definitions */ #define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ #define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ #define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ #define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ #define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ #define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ /* SCB Debug Fault Status Register Definitions */ #define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ #define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ #define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ #define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ #define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ #define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ #define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ #define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ #define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ #define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ /* SCB Non-Secure Access Control Register Definitions */ #define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ #define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ #define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ #define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ #define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ #define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ /* SCB Cache Level ID Register Definitions */ #define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ #define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ #define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ #define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ /* SCB Cache Type Register Definitions */ #define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ #define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ #define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ #define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ #define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ #define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ #define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ #define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ #define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ #define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ /* SCB Cache Size ID Register Definitions */ #define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ #define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ #define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ #define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ #define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ #define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ #define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ #define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ #define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ #define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ #define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ #define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ #define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ #define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ /* SCB Cache Size Selection Register Definitions */ #define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ #define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ #define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ #define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ /* SCB Software Triggered Interrupt Register Definitions */ #define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ #define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ /* SCB D-Cache Invalidate by Set-way Register Definitions */ #define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ #define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ #define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ #define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ /* SCB D-Cache Clean by Set-way Register Definitions */ #define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ #define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ #define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ #define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ /* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ #define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ #define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ #define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ #define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ /* Instruction Tightly-Coupled Memory Control Register Definitions */ #define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ #define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ #define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ #define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ #define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ #define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ #define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ #define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ /* Data Tightly-Coupled Memory Control Register Definitions */ #define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ #define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ #define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ #define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ #define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ #define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ #define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ #define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ /* AHBP Control Register Definitions */ #define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ #define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ #define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ #define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ /* L1 Cache Control Register Definitions */ #define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ #define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ #define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ #define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ #define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ #define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ /* AHBS Control Register Definitions */ #define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ #define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ #define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ #define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ #define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ #define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ /* Auxiliary Bus Fault Status Register Definitions */ #define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ #define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ #define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ #define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ #define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ #define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ #define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ #define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ #define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ #define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ #define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ #define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ /*@} end of group CMSIS_SCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) \brief Type definitions for the System Control and ID Register not in the SCB @{ */ /** \brief Structure type to access the System Control and ID Register not in the SCB. */ typedef struct { uint32_t RESERVED0[1U]; __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ } SCnSCB_Type; /* Interrupt Controller Type Register Definitions */ #define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ #define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ /*@} end of group CMSIS_SCnotSCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SysTick System Tick Timer (SysTick) \brief Type definitions for the System Timer Registers. @{ */ /** \brief Structure type to access the System Timer (SysTick). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; /* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ /* SysTick Calibration Register Definitions */ #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ /*@} end of group CMSIS_SysTick */ /** \ingroup CMSIS_core_register \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) \brief Type definitions for the Instrumentation Trace Macrocell (ITM) @{ */ /** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). */ typedef struct { __OM union { __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ uint32_t RESERVED0[864U]; __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ uint32_t RESERVED1[15U]; __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ uint32_t RESERVED2[15U]; __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ uint32_t RESERVED3[29U]; __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ uint32_t RESERVED4[43U]; __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ uint32_t RESERVED5[1U]; __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ uint32_t RESERVED6[4U]; __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ } ITM_Type; /* ITM Stimulus Port Register Definitions */ #define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ #define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ #define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ #define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ /* ITM Trace Privilege Register Definitions */ #define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ #define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ /* ITM Trace Control Register Definitions */ #define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ #define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ #define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ #define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ #define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ #define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ #define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ #define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ #define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ #define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ #define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ #define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ #define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ #define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ #define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ #define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ #define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ #define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ #define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ #define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ /* ITM Integration Write Register Definitions */ #define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ #define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ /* ITM Integration Read Register Definitions */ #define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ #define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ /* ITM Integration Mode Control Register Definitions */ #define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ #define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ /* ITM Lock Status Register Definitions */ #define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ #define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ #define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ #define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ #define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ #define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ /*@}*/ /* end of group CMSIS_ITM */ /** \ingroup CMSIS_core_register \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) \brief Type definitions for the Data Watchpoint and Trace (DWT) @{ */ /** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ uint32_t RESERVED1[1U]; __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ uint32_t RESERVED2[1U]; __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ uint32_t RESERVED3[1U]; __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ uint32_t RESERVED4[1U]; __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ uint32_t RESERVED5[1U]; __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ uint32_t RESERVED6[1U]; __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ uint32_t RESERVED7[1U]; __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ uint32_t RESERVED8[1U]; __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ uint32_t RESERVED9[1U]; __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ uint32_t RESERVED10[1U]; __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ uint32_t RESERVED11[1U]; __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ uint32_t RESERVED12[1U]; __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ uint32_t RESERVED13[1U]; __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ uint32_t RESERVED14[1U]; __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ uint32_t RESERVED15[1U]; __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ uint32_t RESERVED16[1U]; __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ uint32_t RESERVED17[1U]; __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ uint32_t RESERVED18[1U]; __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ uint32_t RESERVED19[1U]; __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ uint32_t RESERVED20[1U]; __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ uint32_t RESERVED21[1U]; __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ uint32_t RESERVED22[1U]; __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ uint32_t RESERVED23[1U]; __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ uint32_t RESERVED24[1U]; __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ uint32_t RESERVED25[1U]; __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ uint32_t RESERVED26[1U]; __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ uint32_t RESERVED27[1U]; __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ uint32_t RESERVED28[1U]; __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ uint32_t RESERVED29[1U]; __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ uint32_t RESERVED30[1U]; __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ uint32_t RESERVED31[1U]; __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ uint32_t RESERVED32[934U]; __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ uint32_t RESERVED33[1U]; __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ } DWT_Type; /* DWT Control Register Definitions */ #define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ #define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ #define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ #define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ #define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ #define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ #define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ #define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ #define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ #define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ #define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ #define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ #define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ #define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ #define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ #define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ #define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ #define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ #define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ #define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ #define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ #define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ #define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ #define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ #define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ #define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ #define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ #define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ #define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ #define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ #define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ #define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ #define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ #define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ #define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ #define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ #define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ #define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ /* DWT CPI Count Register Definitions */ #define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ #define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ /* DWT Exception Overhead Count Register Definitions */ #define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ #define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ /* DWT Sleep Count Register Definitions */ #define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ #define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ /* DWT LSU Count Register Definitions */ #define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ #define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ /* DWT Folded-instruction Count Register Definitions */ #define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ #define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ /* DWT Comparator Function Register Definitions */ #define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ #define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ #define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ #define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ #define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ #define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ #define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ #define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ #define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ #define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ /*@}*/ /* end of group CMSIS_DWT */ /** \ingroup CMSIS_core_register \defgroup CMSIS_TPI Trace Port Interface (TPI) \brief Type definitions for the Trace Port Interface (TPI) @{ */ /** \brief Structure type to access the Trace Port Interface Register (TPI). */ typedef struct { __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ uint32_t RESERVED1[55U]; __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ uint32_t RESERVED2[131U]; __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ uint32_t RESERVED3[759U]; __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ uint32_t RESERVED4[1U]; __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ uint32_t RESERVED5[39U]; __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ uint32_t RESERVED7[8U]; __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ } TPI_Type; /* TPI Asynchronous Clock Prescaler Register Definitions */ #define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ #define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ /* TPI Selected Pin Protocol Register Definitions */ #define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ #define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ /* TPI Formatter and Flush Status Register Definitions */ #define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ #define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ #define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ #define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ #define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ #define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ #define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ #define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ /* TPI Formatter and Flush Control Register Definitions */ #define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ #define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ #define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ #define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ /* TPI TRIGGER Register Definitions */ #define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ #define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ /* TPI Integration ETM Data Register Definitions (FIFO0) */ #define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ #define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ #define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ #define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ #define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ #define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ #define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ #define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ #define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ #define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ #define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ #define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ #define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ #define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ /* TPI ITATBCTR2 Register Definitions */ #define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ #define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ /* TPI Integration ITM Data Register Definitions (FIFO1) */ #define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ #define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ #define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ #define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ #define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ #define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ #define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ #define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ #define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ #define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ #define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ #define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ #define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ #define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ /* TPI ITATBCTR0 Register Definitions */ #define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ #define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ /* TPI Integration Mode Control Register Definitions */ #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ #define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ #define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ #define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ #define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ #define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ #define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ #define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ #define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ #define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ #define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ #define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ #define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ #define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ #define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ #define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ /*@}*/ /* end of group CMSIS_TPI */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) /** \ingroup CMSIS_core_register \defgroup CMSIS_MPU Memory Protection Unit (MPU) \brief Type definitions for the Memory Protection Unit (MPU) @{ */ /** \brief Structure type to access the Memory Protection Unit (MPU). */ typedef struct { __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ uint32_t RESERVED0[1]; union { __IOM uint32_t MAIR[2]; struct { __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ }; }; } MPU_Type; #define MPU_TYPE_RALIASES 4U /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ #define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ #define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ #define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ #define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ /* MPU Control Register Definitions */ #define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ #define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ #define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ #define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ #define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ #define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ /* MPU Region Number Register Definitions */ #define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ #define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ /* MPU Region Base Address Register Definitions */ #define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ #define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ #define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ #define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ #define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ #define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ #define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ #define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ /* MPU Region Limit Address Register Definitions */ #define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ #define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ #define MPU_RLAR_PXN_Pos 4U /*!< MPU RLAR: PXN Position */ #define MPU_RLAR_PXN_Msk (0x1UL << MPU_RLAR_PXN_Pos) /*!< MPU RLAR: PXN Mask */ #define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ #define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ #define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ #define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ /* MPU Memory Attribute Indirection Register 0 Definitions */ #define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ #define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ #define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ #define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ #define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ #define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ #define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ #define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ /* MPU Memory Attribute Indirection Register 1 Definitions */ #define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ #define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ #define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ #define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ #define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ #define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ #define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ #define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ /*@} end of group CMSIS_MPU */ #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \ingroup CMSIS_core_register \defgroup CMSIS_SAU Security Attribution Unit (SAU) \brief Type definitions for the Security Attribution Unit (SAU) @{ */ /** \brief Structure type to access the Security Attribution Unit (SAU). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ #if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ #else uint32_t RESERVED0[3]; #endif __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ } SAU_Type; /* SAU Control Register Definitions */ #define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ #define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ #define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ #define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ /* SAU Type Register Definitions */ #define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ #define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ #if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) /* SAU Region Number Register Definitions */ #define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ #define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ /* SAU Region Base Address Register Definitions */ #define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ #define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ /* SAU Region Limit Address Register Definitions */ #define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ #define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ #define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ #define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ #define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ #define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ #endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ /* Secure Fault Status Register Definitions */ #define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ #define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ #define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ #define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ #define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ #define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ #define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ #define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ #define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ #define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ #define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ #define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ #define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ #define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ #define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ #define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ /*@} end of group CMSIS_SAU */ #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /** \ingroup CMSIS_core_register \defgroup CMSIS_FPU Floating Point Unit (FPU) \brief Type definitions for the Floating Point Unit (FPU) @{ */ /** \brief Structure type to access the Floating Point Unit (FPU). */ typedef struct { uint32_t RESERVED0[1U]; __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ } FPU_Type; /* Floating-Point Context Control Register Definitions */ #define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ #define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ #define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ #define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ #define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ #define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ #define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ #define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ #define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ #define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ #define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ #define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ #define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ #define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ #define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ #define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ #define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ #define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ #define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ #define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ #define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ #define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ #define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ #define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ #define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ #define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ #define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ #define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ #define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ #define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ #define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ #define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ #define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ #define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ /* Floating-Point Context Address Register Definitions */ #define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ #define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ /* Floating-Point Default Status Control Register Definitions */ #define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ #define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ #define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ #define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ #define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ #define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ #define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ #define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ /* Media and FP Feature Register 0 Definitions */ #define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ #define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ #define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ #define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ #define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ #define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ #define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ #define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ #define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ #define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ #define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ #define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ #define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ #define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ #define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ #define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ /* Media and FP Feature Register 1 Definitions */ #define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ #define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ #define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ #define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ #define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ #define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ #define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ #define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ /*@} end of group CMSIS_FPU */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) \brief Type definitions for the Core Debug Registers @{ */ /** \brief Structure type to access the Core Debug Register (CoreDebug). */ typedef struct { __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ uint32_t RESERVED4[1U]; __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ } CoreDebug_Type; /* Debug Halting Control and Status Register Definitions */ #define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ #define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ #define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ #define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ #define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ #define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ #define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ #define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ #define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ #define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ #define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ #define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ #define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ #define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ #define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ #define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ #define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ #define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ #define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ #define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ #define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ #define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ #define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ #define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ /* Debug Core Register Selector Register Definitions */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ #define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ /* Debug Exception and Monitor Control Register Definitions */ #define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ #define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ #define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ #define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ #define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ #define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ #define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ #define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ #define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ #define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ #define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ #define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ #define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ #define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ #define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ #define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ #define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ #define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ #define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ #define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ #define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ #define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ #define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ #define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ #define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ #define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ /* Debug Authentication Control Register Definitions */ #define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ #define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ #define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ #define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ #define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ #define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ #define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ #define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ /* Debug Security Control and Status Register Definitions */ #define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ #define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ #define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ #define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ #define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ #define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ /*@} end of group CMSIS_CoreDebug */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_bitfield Core register bit field macros \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). @{ */ /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_base Core Definitions \brief Definitions for base addresses, unions, and structures. @{ */ /* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ #endif #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ #endif #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /*@} */ /******************************************************************************* * Hardware Abstraction Layer Core Function Interface contains: - Core NVIC Functions - Core SysTick Functions - Core Debug Functions - Core Register Access Functions ******************************************************************************/ /** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference */ /* ########################## NVIC functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_NVICFunctions NVIC Functions \brief Functions that manage interrupts and exceptions via the NVIC. @{ */ #ifdef CMSIS_NVIC_VIRTUAL #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" #endif #include CMSIS_NVIC_VIRTUAL_HEADER_FILE #else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ #define NVIC_GetActive __NVIC_GetActive #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ #ifdef CMSIS_VECTAB_VIRTUAL #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" #endif #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE #else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ #define NVIC_USER_IRQ_OFFSET 16 /** \brief Set Priority Grouping \details Sets the priority grouping field using the required unlock sequence. The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Priority grouping field. */ __STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ reg_value = SCB->AIRCR; /* read old register configuration */ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ SCB->AIRCR = reg_value; } /** \brief Get Priority Grouping \details Reads the priority grouping field from the NVIC Interrupt Controller. \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ __STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) { return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); } /** \brief Enable Interrupt \details Enables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Interrupt Enable status \details Returns a device specific interrupt enable status from the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt \details Disables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } } /** \brief Get Pending Interrupt \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt \details Sets the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt \details Clears the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Get Interrupt Target State \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure \return 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Target State \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Clear Interrupt Target State \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /** \brief Set Interrupt Priority \details Sets the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every processor exception. */ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } /** \brief Get Interrupt Priority \details Reads the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } /** \brief Encode Priority \details Encodes the priority for an interrupt with the given priority group, preemptive priority value, and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Used priority group. \param [in] PreemptPriority Preemptive priority value (starting from 0). \param [in] SubPriority Subpriority value (starting from 0). \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). */ __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); return ( ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) ); } /** \brief Decode Priority \details Decodes an interrupt priority value with a given priority group to preemptive priority value and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). \param [in] PriorityGroup Used priority group. \param [out] pPreemptPriority Preemptive priority value (starting from 0). \param [out] pSubPriority Subpriority value (starting from 0). */ __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); } /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. VTOR must been relocated to SRAM before. \param [in] IRQn Interrupt number \param [in] vector Address of interrupt handler function */ __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { uint32_t *vectors = (uint32_t *)SCB->VTOR; vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; __DSB(); } /** \brief Get Interrupt Vector \details Reads an interrupt vector from interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Address of interrupt handler function */ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) { uint32_t *vectors = (uint32_t *)SCB->VTOR; return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; } /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ __DSB(); /* Ensure completion of memory access */ for(;;) /* wait until reset */ { __NOP(); } } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Set Priority Grouping (non-secure) \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Priority grouping field. */ __STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ reg_value = SCB_NS->AIRCR; /* read old register configuration */ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ SCB_NS->AIRCR = reg_value; } /** \brief Get Priority Grouping (non-secure) \details Reads the priority grouping field from the non-secure NVIC when in secure state. \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ __STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) { return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); } /** \brief Enable Interrupt (non-secure) \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Interrupt Enable status (non-secure) \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt (non-secure) \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Pending Interrupt (non-secure) \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt (non-secure) \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt (non-secure) \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt (non-secure) \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Priority (non-secure) \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every non-secure processor exception. */ __STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } /** \brief Get Interrupt Priority (non-secure) \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } #endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ /*@} end of CMSIS_Core_NVICFunctions */ /* ########################## MPU functions #################################### */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #include "mpu_armv8.h" #endif /* ########################## FPU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_FpuFunctions FPU Functions \brief Function that provides FPU type. @{ */ /** \brief get FPU type \details returns the FPU type \returns - \b 0: No FPU - \b 1: Single precision FPU - \b 2: Double + Single precision FPU */ __STATIC_INLINE uint32_t SCB_GetFPUType(void) { uint32_t mvfr0; mvfr0 = FPU->MVFR0; if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) { return 2U; /* Double + Single precision FPU */ } else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) { return 1U; /* Single precision FPU */ } else { return 0U; /* No FPU */ } } /*@} end of CMSIS_Core_FpuFunctions */ /* ########################## SAU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SAUFunctions SAU Functions \brief Functions that configure the SAU. @{ */ #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Enable SAU \details Enables the Security Attribution Unit (SAU). */ __STATIC_INLINE void TZ_SAU_Enable(void) { SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); } /** \brief Disable SAU \details Disables the Security Attribution Unit (SAU). */ __STATIC_INLINE void TZ_SAU_Disable(void) { SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /*@} end of CMSIS_Core_SAUFunctions */ /* ################################## SysTick function ############################################ */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SysTickFunctions SysTick Functions \brief Functions that configure the System. @{ */ #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief System Tick Configuration (non-secure) \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function TZ_SysTick_Config_NS is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ #endif /*@} end of CMSIS_Core_SysTickFunctions */ /* ##################################### Debug In/Output function ########################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_core_DebugFunctions ITM Functions \brief Functions that access the ITM debug interface. @{ */ extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ #define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ /** \brief ITM Send Character \details Transmits a character via the ITM channel 0, and \li Just returns when no debugger is connected that has booked the output. \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. \param [in] ch Character to transmit. \returns Character to transmit. */ __STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) { if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ { while (ITM->PORT[0U].u32 == 0UL) { __NOP(); } ITM->PORT[0U].u8 = (uint8_t)ch; } return (ch); } /** \brief ITM Receive Character \details Inputs a character via the external variable \ref ITM_RxBuffer. \return Received character. \return -1 No character pending. */ __STATIC_INLINE int32_t ITM_ReceiveChar (void) { int32_t ch = -1; /* no character available */ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { ch = ITM_RxBuffer; ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ } return (ch); } /** \brief ITM Check Character \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. \return 0 No character available. \return 1 Character available. */ __STATIC_INLINE int32_t ITM_CheckChar (void) { if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { return (0); /* no character available */ } else { return (1); /* character available */ } } /*@} end of CMSIS_core_DebugFunctions */ #ifdef __cplusplus } #endif #endif /* __CORE_ARMV81MML_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ ================================================ FILE: 3rd_party/CMSIS/Include/core_armv8mbl.h ================================================ /**************************************************************************//** * @file core_armv8mbl.h * @brief CMSIS Armv8-M Baseline Core Peripheral Access Layer Header File * @version V5.0.8 * @date 12. November 2018 ******************************************************************************/ /* * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_ARMV8MBL_H_GENERIC #define __CORE_ARMV8MBL_H_GENERIC #include #ifdef __cplusplus extern "C" { #endif /** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions CMSIS violates the following MISRA-C:2004 rules: \li Required Rule 8.5, object/function definition in header file.
Function definitions in header files are used to allow 'inlining'. \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
Unions are used for effective representation of core registers. \li Advisory Rule 19.7, Function-like macro defined.
Function-like macros are used to allow more efficient code. */ /******************************************************************************* * CMSIS definitions ******************************************************************************/ /** \ingroup Cortex_ARMv8MBL @{ */ #include "cmsis_version.h" /* CMSIS definitions */ #define __ARMv8MBL_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ #define __ARMv8MBL_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __ARMv8MBL_CMSIS_VERSION ((__ARMv8MBL_CMSIS_VERSION_MAIN << 16U) | \ __ARMv8MBL_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M ( 2U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all */ #define __FPU_USED 0U #if defined ( __CC_ARM ) #if defined __TARGET_FPU_VFP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined __ARM_FP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TASKING__ ) #if defined __FPU_VFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __CSMC__ ) #if ( __CSMC__ & 0x400U) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #endif #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ #ifdef __cplusplus } #endif #endif /* __CORE_ARMV8MBL_H_GENERIC */ #ifndef __CMSIS_GENERIC #ifndef __CORE_ARMV8MBL_H_DEPENDANT #define __CORE_ARMV8MBL_H_DEPENDANT #ifdef __cplusplus extern "C" { #endif /* check device defines and use defaults */ #if defined __CHECK_DEVICE_DEFINES #ifndef __ARMv8MBL_REV #define __ARMv8MBL_REV 0x0000U #warning "__ARMv8MBL_REV not defined in device header file; using default!" #endif #ifndef __FPU_PRESENT #define __FPU_PRESENT 0U #warning "__FPU_PRESENT not defined in device header file; using default!" #endif #ifndef __MPU_PRESENT #define __MPU_PRESENT 0U #warning "__MPU_PRESENT not defined in device header file; using default!" #endif #ifndef __SAUREGION_PRESENT #define __SAUREGION_PRESENT 0U #warning "__SAUREGION_PRESENT not defined in device header file; using default!" #endif #ifndef __VTOR_PRESENT #define __VTOR_PRESENT 0U #warning "__VTOR_PRESENT not defined in device header file; using default!" #endif #ifndef __NVIC_PRIO_BITS #define __NVIC_PRIO_BITS 2U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif #ifndef __Vendor_SysTickConfig #define __Vendor_SysTickConfig 0U #warning "__Vendor_SysTickConfig not defined in device header file; using default!" #endif #ifndef __ETM_PRESENT #define __ETM_PRESENT 0U #warning "__ETM_PRESENT not defined in device header file; using default!" #endif #ifndef __MTB_PRESENT #define __MTB_PRESENT 0U #warning "__MTB_PRESENT not defined in device header file; using default!" #endif #endif /* IO definitions (access restrictions to peripheral registers) */ /** \defgroup CMSIS_glob_defs CMSIS Global Defines IO Type Qualifiers are used \li to specify the access to peripheral variables. \li for automatic generation of peripheral register debug information. */ #ifdef __cplusplus #define __I volatile /*!< Defines 'read only' permissions */ #else #define __I volatile const /*!< Defines 'read only' permissions */ #endif #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */ /* following defines should be used for structure members */ #define __IM volatile const /*! Defines 'read only' structure member permissions */ #define __OM volatile /*! Defines 'write only' structure member permissions */ #define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group ARMv8MBL */ /******************************************************************************* * Register Abstraction Core Register contain: - Core Register - Core NVIC Register - Core SCB Register - Core SysTick Register - Core Debug Register - Core MPU Register - Core SAU Register ******************************************************************************/ /** \defgroup CMSIS_core_register Defines and Type Definitions \brief Type definitions and defines for Cortex-M processor based devices. */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CORE Status and Control Registers \brief Core Register type definitions. @{ */ /** \brief Union type to access the Application Program Status Register (APSR). */ typedef union { struct { uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } APSR_Type; /* APSR Register Definitions */ #define APSR_N_Pos 31U /*!< APSR: N Position */ #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ #define APSR_Z_Pos 30U /*!< APSR: Z Position */ #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ #define APSR_C_Pos 29U /*!< APSR: C Position */ #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ #define APSR_V_Pos 28U /*!< APSR: V Position */ #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ /** \brief Union type to access the Interrupt Program Status Register (IPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } IPSR_Type; /* IPSR Register Definitions */ #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ /** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } xPSR_Type; /* xPSR Register Definitions */ #define xPSR_N_Pos 31U /*!< xPSR: N Position */ #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ #define xPSR_C_Pos 29U /*!< xPSR: C Position */ #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ #define xPSR_V_Pos 28U /*!< xPSR: V Position */ #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ /** \brief Union type to access the Control Registers (CONTROL). */ typedef union { struct { uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } CONTROL_Type; /* CONTROL Register Definitions */ #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ #define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ #define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ /*@} end of group CMSIS_CORE */ /** \ingroup CMSIS_core_register \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) \brief Type definitions for the NVIC Registers @{ */ /** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). */ typedef struct { __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[16U]; __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ uint32_t RSERVED1[16U]; __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[16U]; __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ uint32_t RESERVED3[16U]; __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ uint32_t RESERVED4[16U]; __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ uint32_t RESERVED5[16U]; __IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ } NVIC_Type; /*@} end of group CMSIS_NVIC */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCB System Control Block (SCB) \brief Type definitions for the System Control Block Registers @{ */ /** \brief Structure type to access the System Control Block (SCB). */ typedef struct { __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ #if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ #else uint32_t RESERVED0; #endif __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ uint32_t RESERVED1; __IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ } SCB_Type; /* SCB CPUID Register Definitions */ #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ /* SCB Interrupt Control State Register Definitions */ #define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ #define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ #define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ #define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ #define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ #define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ #define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ #define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ #define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ #define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ #if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) /* SCB Vector Table Offset Register Definitions */ #define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ #define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ #endif /* SCB Application Interrupt and Reset Control Register Definitions */ #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ #define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ #define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ #define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ #define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ #define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ #define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ /* SCB System Control Register Definitions */ #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ #define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ #define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ /* SCB Configuration Control Register Definitions */ #define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ #define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ #define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ #define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ #define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ #define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ #define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ #define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ #define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ #define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ #define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ #define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ #define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ #define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ /* SCB System Handler Control and State Register Definitions */ #define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ #define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ #define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ #define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ #define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ #define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ #define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ #define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ #define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ #define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ #define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ #define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ /*@} end of group CMSIS_SCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SysTick System Tick Timer (SysTick) \brief Type definitions for the System Timer Registers. @{ */ /** \brief Structure type to access the System Timer (SysTick). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; /* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ /* SysTick Calibration Register Definitions */ #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ /*@} end of group CMSIS_SysTick */ /** \ingroup CMSIS_core_register \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) \brief Type definitions for the Data Watchpoint and Trace (DWT) @{ */ /** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ uint32_t RESERVED0[6U]; __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ uint32_t RESERVED1[1U]; __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ uint32_t RESERVED2[1U]; __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ uint32_t RESERVED3[1U]; __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ uint32_t RESERVED4[1U]; __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ uint32_t RESERVED5[1U]; __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ uint32_t RESERVED6[1U]; __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ uint32_t RESERVED7[1U]; __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ uint32_t RESERVED8[1U]; __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ uint32_t RESERVED9[1U]; __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ uint32_t RESERVED10[1U]; __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ uint32_t RESERVED11[1U]; __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ uint32_t RESERVED12[1U]; __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ uint32_t RESERVED13[1U]; __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ uint32_t RESERVED14[1U]; __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ uint32_t RESERVED15[1U]; __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ uint32_t RESERVED16[1U]; __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ uint32_t RESERVED17[1U]; __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ uint32_t RESERVED18[1U]; __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ uint32_t RESERVED19[1U]; __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ uint32_t RESERVED20[1U]; __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ uint32_t RESERVED21[1U]; __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ uint32_t RESERVED22[1U]; __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ uint32_t RESERVED23[1U]; __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ uint32_t RESERVED24[1U]; __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ uint32_t RESERVED25[1U]; __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ uint32_t RESERVED26[1U]; __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ uint32_t RESERVED27[1U]; __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ uint32_t RESERVED28[1U]; __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ uint32_t RESERVED29[1U]; __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ uint32_t RESERVED30[1U]; __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ uint32_t RESERVED31[1U]; __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ } DWT_Type; /* DWT Control Register Definitions */ #define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ #define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ #define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ #define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ #define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ #define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ #define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ #define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ #define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ #define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ /* DWT Comparator Function Register Definitions */ #define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ #define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ #define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ #define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ #define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ #define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ #define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ #define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ #define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ #define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ /*@}*/ /* end of group CMSIS_DWT */ /** \ingroup CMSIS_core_register \defgroup CMSIS_TPI Trace Port Interface (TPI) \brief Type definitions for the Trace Port Interface (TPI) @{ */ /** \brief Structure type to access the Trace Port Interface Register (TPI). */ typedef struct { __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ uint32_t RESERVED1[55U]; __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ uint32_t RESERVED2[131U]; __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ uint32_t RESERVED3[809U]; __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ uint32_t RESERVED4[4U]; __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ } TPI_Type; /* TPI Asynchronous Clock Prescaler Register Definitions */ #define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ #define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ /* TPI Selected Pin Protocol Register Definitions */ #define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ #define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ /* TPI Formatter and Flush Status Register Definitions */ #define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ #define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ #define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ #define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ #define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ #define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ #define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ #define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ /* TPI Formatter and Flush Control Register Definitions */ #define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ #define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ #define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ #define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ #define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ #define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ /* TPI Periodic Synchronization Control Register Definitions */ #define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ #define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ /* TPI Software Lock Status Register Definitions */ #define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ #define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ #define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ #define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ #define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ #define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ #define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ #define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ #define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ #define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ #define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ #define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ #define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ /* TPI DEVTYPE Register Definitions */ #define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ #define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ #define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ /*@}*/ /* end of group CMSIS_TPI */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) /** \ingroup CMSIS_core_register \defgroup CMSIS_MPU Memory Protection Unit (MPU) \brief Type definitions for the Memory Protection Unit (MPU) @{ */ /** \brief Structure type to access the Memory Protection Unit (MPU). */ typedef struct { __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ uint32_t RESERVED0[7U]; union { __IOM uint32_t MAIR[2]; struct { __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ }; }; } MPU_Type; #define MPU_TYPE_RALIASES 1U /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ #define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ #define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ #define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ #define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ /* MPU Control Register Definitions */ #define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ #define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ #define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ #define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ #define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ #define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ /* MPU Region Number Register Definitions */ #define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ #define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ /* MPU Region Base Address Register Definitions */ #define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ #define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ #define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ #define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ #define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ #define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ #define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ #define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ /* MPU Region Limit Address Register Definitions */ #define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ #define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ #define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ #define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ #define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */ #define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */ /* MPU Memory Attribute Indirection Register 0 Definitions */ #define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ #define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ #define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ #define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ #define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ #define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ #define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ #define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ /* MPU Memory Attribute Indirection Register 1 Definitions */ #define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ #define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ #define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ #define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ #define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ #define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ #define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ #define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ /*@} end of group CMSIS_MPU */ #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \ingroup CMSIS_core_register \defgroup CMSIS_SAU Security Attribution Unit (SAU) \brief Type definitions for the Security Attribution Unit (SAU) @{ */ /** \brief Structure type to access the Security Attribution Unit (SAU). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ #if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ #endif } SAU_Type; /* SAU Control Register Definitions */ #define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ #define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ #define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ #define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ /* SAU Type Register Definitions */ #define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ #define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ #if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) /* SAU Region Number Register Definitions */ #define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ #define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ /* SAU Region Base Address Register Definitions */ #define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ #define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ /* SAU Region Limit Address Register Definitions */ #define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ #define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ #define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ #define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ #define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ #define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ #endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ /*@} end of group CMSIS_SAU */ #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) \brief Type definitions for the Core Debug Registers @{ */ /** \brief Structure type to access the Core Debug Register (CoreDebug). */ typedef struct { __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ uint32_t RESERVED4[1U]; __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ } CoreDebug_Type; /* Debug Halting Control and Status Register Definitions */ #define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ #define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ #define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ #define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ #define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ #define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ #define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ #define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ #define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ #define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ #define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ #define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ #define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ #define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ #define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ #define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ #define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ #define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ #define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ #define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ #define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ #define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ /* Debug Core Register Selector Register Definitions */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ #define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ /* Debug Exception and Monitor Control Register */ #define CoreDebug_DEMCR_DWTENA_Pos 24U /*!< CoreDebug DEMCR: DWTENA Position */ #define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< CoreDebug DEMCR: DWTENA Mask */ #define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ #define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ #define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ #define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ /* Debug Authentication Control Register Definitions */ #define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ #define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ #define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ #define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ #define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ #define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ #define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ #define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ /* Debug Security Control and Status Register Definitions */ #define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ #define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ #define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ #define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ #define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ #define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ /*@} end of group CMSIS_CoreDebug */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_bitfield Core register bit field macros \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). @{ */ /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_base Core Definitions \brief Definitions for base addresses, unions, and structures. @{ */ /* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ #endif #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /*@} */ /******************************************************************************* * Hardware Abstraction Layer Core Function Interface contains: - Core NVIC Functions - Core SysTick Functions - Core Register Access Functions ******************************************************************************/ /** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference */ /* ########################## NVIC functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_NVICFunctions NVIC Functions \brief Functions that manage interrupts and exceptions via the NVIC. @{ */ #ifdef CMSIS_NVIC_VIRTUAL #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" #endif #include CMSIS_NVIC_VIRTUAL_HEADER_FILE #else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ #define NVIC_GetActive __NVIC_GetActive #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ #ifdef CMSIS_VECTAB_VIRTUAL #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" #endif #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE #else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ #define NVIC_USER_IRQ_OFFSET 16 /* Special LR values for Secure/Non-Secure call handling and exception handling */ /* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ #define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ /* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ #define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ #define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ #define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ #define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ #define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ #define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ #define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ /* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ #define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ #else #define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ #endif /* Interrupt Priorities are WORD accessible only under Armv6-M */ /* The following MACROS handle generation of the register offset and byte masks */ #define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) #define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) #define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) #define __NVIC_SetPriorityGrouping(X) (void)(X) #define __NVIC_GetPriorityGrouping() (0U) /** \brief Enable Interrupt \details Enables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { __COMPILER_BARRIER(); NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __COMPILER_BARRIER(); } } /** \brief Get Interrupt Enable status \details Returns a device specific interrupt enable status from the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt \details Disables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } } /** \brief Get Pending Interrupt \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt \details Sets the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt \details Clears the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Get Interrupt Target State \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure \return 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Target State \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Clear Interrupt Target State \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /** \brief Set Interrupt Priority \details Sets the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every processor exception. */ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } else { SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } } /** \brief Get Interrupt Priority \details Reads the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } else { return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } } /** \brief Encode Priority \details Encodes the priority for an interrupt with the given priority group, preemptive priority value, and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Used priority group. \param [in] PreemptPriority Preemptive priority value (starting from 0). \param [in] SubPriority Subpriority value (starting from 0). \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). */ __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); return ( ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) ); } /** \brief Decode Priority \details Decodes an interrupt priority value with a given priority group to preemptive priority value and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). \param [in] PriorityGroup Used priority group. \param [out] pPreemptPriority Preemptive priority value (starting from 0). \param [out] pSubPriority Subpriority value (starting from 0). */ __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); } /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. VTOR must been relocated to SRAM before. If VTOR is not present address 0 must be mapped to SRAM. \param [in] IRQn Interrupt number \param [in] vector Address of interrupt handler function */ __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { #if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) uint32_t *vectors = (uint32_t *)SCB->VTOR; #else uint32_t *vectors = (uint32_t *)0x0U; #endif vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; __DSB(); } /** \brief Get Interrupt Vector \details Reads an interrupt vector from interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Address of interrupt handler function */ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) { #if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) uint32_t *vectors = (uint32_t *)SCB->VTOR; #else uint32_t *vectors = (uint32_t *)0x0U; #endif return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; } /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk); __DSB(); /* Ensure completion of memory access */ for(;;) /* wait until reset */ { __NOP(); } } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Enable Interrupt (non-secure) \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Interrupt Enable status (non-secure) \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt (non-secure) \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Pending Interrupt (non-secure) \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt (non-secure) \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt (non-secure) \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt (non-secure) \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Priority (non-secure) \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every non-secure processor exception. */ __STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } else { SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } } /** \brief Get Interrupt Priority (non-secure) \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } else { return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } } #endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ /*@} end of CMSIS_Core_NVICFunctions */ /* ########################## MPU functions #################################### */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #include "mpu_armv8.h" #endif /* ########################## FPU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_FpuFunctions FPU Functions \brief Function that provides FPU type. @{ */ /** \brief get FPU type \details returns the FPU type \returns - \b 0: No FPU - \b 1: Single precision FPU - \b 2: Double + Single precision FPU */ __STATIC_INLINE uint32_t SCB_GetFPUType(void) { return 0U; /* No FPU */ } /*@} end of CMSIS_Core_FpuFunctions */ /* ########################## SAU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SAUFunctions SAU Functions \brief Functions that configure the SAU. @{ */ #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Enable SAU \details Enables the Security Attribution Unit (SAU). */ __STATIC_INLINE void TZ_SAU_Enable(void) { SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); } /** \brief Disable SAU \details Disables the Security Attribution Unit (SAU). */ __STATIC_INLINE void TZ_SAU_Disable(void) { SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /*@} end of CMSIS_Core_SAUFunctions */ /* ################################## SysTick function ############################################ */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SysTickFunctions SysTick Functions \brief Functions that configure the System. @{ */ #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief System Tick Configuration (non-secure) \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function TZ_SysTick_Config_NS is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ #endif /*@} end of CMSIS_Core_SysTickFunctions */ #ifdef __cplusplus } #endif #endif /* __CORE_ARMV8MBL_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ ================================================ FILE: 3rd_party/CMSIS/Include/core_armv8mml.h ================================================ /**************************************************************************//** * @file core_armv8mml.h * @brief CMSIS Armv8-M Mainline Core Peripheral Access Layer Header File * @version V5.1.0 * @date 12. September 2018 ******************************************************************************/ /* * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_ARMV8MML_H_GENERIC #define __CORE_ARMV8MML_H_GENERIC #include #ifdef __cplusplus extern "C" { #endif /** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions CMSIS violates the following MISRA-C:2004 rules: \li Required Rule 8.5, object/function definition in header file.
Function definitions in header files are used to allow 'inlining'. \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
Unions are used for effective representation of core registers. \li Advisory Rule 19.7, Function-like macro defined.
Function-like macros are used to allow more efficient code. */ /******************************************************************************* * CMSIS definitions ******************************************************************************/ /** \ingroup Cortex_ARMv8MML @{ */ #include "cmsis_version.h" /* CMSIS Armv8MML definitions */ #define __ARMv8MML_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ #define __ARMv8MML_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __ARMv8MML_CMSIS_VERSION ((__ARMv8MML_CMSIS_VERSION_MAIN << 16U) | \ __ARMv8MML_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (81U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. */ #if defined ( __CC_ARM ) #if defined __TARGET_FPU_VFP #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined(__ARM_FEATURE_DSP) #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined __ARM_FP #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined(__ARM_FEATURE_DSP) #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined(__ARM_FEATURE_DSP) #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined(__ARM_FEATURE_DSP) #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __TASKING__ ) #if defined __FPU_VFP__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __CSMC__ ) #if ( __CSMC__ & 0x400U) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #endif #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ #ifdef __cplusplus } #endif #endif /* __CORE_ARMV8MML_H_GENERIC */ #ifndef __CMSIS_GENERIC #ifndef __CORE_ARMV8MML_H_DEPENDANT #define __CORE_ARMV8MML_H_DEPENDANT #ifdef __cplusplus extern "C" { #endif /* check device defines and use defaults */ #if defined __CHECK_DEVICE_DEFINES #ifndef __ARMv8MML_REV #define __ARMv8MML_REV 0x0000U #warning "__ARMv8MML_REV not defined in device header file; using default!" #endif #ifndef __FPU_PRESENT #define __FPU_PRESENT 0U #warning "__FPU_PRESENT not defined in device header file; using default!" #endif #ifndef __MPU_PRESENT #define __MPU_PRESENT 0U #warning "__MPU_PRESENT not defined in device header file; using default!" #endif #ifndef __SAUREGION_PRESENT #define __SAUREGION_PRESENT 0U #warning "__SAUREGION_PRESENT not defined in device header file; using default!" #endif #ifndef __DSP_PRESENT #define __DSP_PRESENT 0U #warning "__DSP_PRESENT not defined in device header file; using default!" #endif #ifndef __NVIC_PRIO_BITS #define __NVIC_PRIO_BITS 3U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif #ifndef __Vendor_SysTickConfig #define __Vendor_SysTickConfig 0U #warning "__Vendor_SysTickConfig not defined in device header file; using default!" #endif #endif /* IO definitions (access restrictions to peripheral registers) */ /** \defgroup CMSIS_glob_defs CMSIS Global Defines IO Type Qualifiers are used \li to specify the access to peripheral variables. \li for automatic generation of peripheral register debug information. */ #ifdef __cplusplus #define __I volatile /*!< Defines 'read only' permissions */ #else #define __I volatile const /*!< Defines 'read only' permissions */ #endif #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */ /* following defines should be used for structure members */ #define __IM volatile const /*! Defines 'read only' structure member permissions */ #define __OM volatile /*! Defines 'write only' structure member permissions */ #define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group ARMv8MML */ /******************************************************************************* * Register Abstraction Core Register contain: - Core Register - Core NVIC Register - Core SCB Register - Core SysTick Register - Core Debug Register - Core MPU Register - Core SAU Register - Core FPU Register ******************************************************************************/ /** \defgroup CMSIS_core_register Defines and Type Definitions \brief Type definitions and defines for Cortex-M processor based devices. */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CORE Status and Control Registers \brief Core Register type definitions. @{ */ /** \brief Union type to access the Application Program Status Register (APSR). */ typedef union { struct { uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } APSR_Type; /* APSR Register Definitions */ #define APSR_N_Pos 31U /*!< APSR: N Position */ #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ #define APSR_Z_Pos 30U /*!< APSR: Z Position */ #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ #define APSR_C_Pos 29U /*!< APSR: C Position */ #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ #define APSR_V_Pos 28U /*!< APSR: V Position */ #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ #define APSR_Q_Pos 27U /*!< APSR: Q Position */ #define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ #define APSR_GE_Pos 16U /*!< APSR: GE Position */ #define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ /** \brief Union type to access the Interrupt Program Status Register (IPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } IPSR_Type; /* IPSR Register Definitions */ #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ /** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } xPSR_Type; /* xPSR Register Definitions */ #define xPSR_N_Pos 31U /*!< xPSR: N Position */ #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ #define xPSR_C_Pos 29U /*!< xPSR: C Position */ #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ #define xPSR_V_Pos 28U /*!< xPSR: V Position */ #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ #define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ #define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ #define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ #define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ #define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ #define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ /** \brief Union type to access the Control Registers (CONTROL). */ typedef union { struct { uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } CONTROL_Type; /* CONTROL Register Definitions */ #define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ #define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ #define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ #define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ #define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ #define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ /*@} end of group CMSIS_CORE */ /** \ingroup CMSIS_core_register \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) \brief Type definitions for the NVIC Registers @{ */ /** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). */ typedef struct { __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[16U]; __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ uint32_t RSERVED1[16U]; __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[16U]; __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ uint32_t RESERVED3[16U]; __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ uint32_t RESERVED4[16U]; __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ uint32_t RESERVED5[16U]; __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ uint32_t RESERVED6[580U]; __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ } NVIC_Type; /* Software Triggered Interrupt Register Definitions */ #define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ #define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ /*@} end of group CMSIS_NVIC */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCB System Control Block (SCB) \brief Type definitions for the System Control Block Registers @{ */ /** \brief Structure type to access the System Control Block (SCB). */ typedef struct { __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ uint32_t RESERVED3[92U]; __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ uint32_t RESERVED4[15U]; __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ uint32_t RESERVED5[1U]; __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ uint32_t RESERVED6[1U]; __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ } SCB_Type; /* SCB CPUID Register Definitions */ #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ /* SCB Interrupt Control State Register Definitions */ #define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ #define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ #define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ #define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ #define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ #define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ #define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ #define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ #define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ #define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ /* SCB Vector Table Offset Register Definitions */ #define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ #define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ /* SCB Application Interrupt and Reset Control Register Definitions */ #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ #define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ #define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ #define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ #define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ #define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ #define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ #define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ #define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ /* SCB System Control Register Definitions */ #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ #define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ #define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ /* SCB Configuration Control Register Definitions */ #define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ #define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ #define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ #define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ #define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ #define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ #define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ #define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ #define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ #define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ #define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ #define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ #define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ #define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ /* SCB System Handler Control and State Register Definitions */ #define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ #define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ #define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ #define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ #define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ #define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ #define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ #define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ #define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ #define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ #define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ #define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ #define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ #define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ #define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ #define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ #define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ #define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ #define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ #define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ #define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ #define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ #define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ #define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ #define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ #define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ #define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ #define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ #define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ #define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ #define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ #define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ #define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ #define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ #define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ #define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ #define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ #define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ /* SCB Configurable Fault Status Register Definitions */ #define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ #define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ #define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ #define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ #define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ #define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ /* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ #define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ #define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ #define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ #define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ #define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ #define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ #define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ #define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ #define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ #define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ #define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ /* BusFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ #define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ #define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ #define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ #define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ #define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ #define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ #define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ #define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ #define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ #define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ #define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ #define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ #define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ /* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ #define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ #define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ #define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ #define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ #define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ #define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ #define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ #define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ #define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ #define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ #define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ #define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ #define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ /* SCB Hard Fault Status Register Definitions */ #define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ #define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ #define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ #define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ #define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ #define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ /* SCB Debug Fault Status Register Definitions */ #define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ #define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ #define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ #define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ #define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ #define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ #define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ #define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ #define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ #define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ /* SCB Non-Secure Access Control Register Definitions */ #define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ #define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ #define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ #define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ #define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ #define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ /* SCB Cache Level ID Register Definitions */ #define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ #define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ #define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ #define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ /* SCB Cache Type Register Definitions */ #define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ #define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ #define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ #define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ #define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ #define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ #define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ #define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ #define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ #define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ /* SCB Cache Size ID Register Definitions */ #define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ #define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ #define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ #define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ #define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ #define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ #define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ #define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ #define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ #define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ #define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ #define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ #define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ #define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ /* SCB Cache Size Selection Register Definitions */ #define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ #define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ #define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ #define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ /* SCB Software Triggered Interrupt Register Definitions */ #define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ #define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ /* SCB D-Cache Invalidate by Set-way Register Definitions */ #define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ #define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ #define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ #define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ /* SCB D-Cache Clean by Set-way Register Definitions */ #define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ #define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ #define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ #define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ /* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ #define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ #define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ #define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ #define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ /*@} end of group CMSIS_SCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) \brief Type definitions for the System Control and ID Register not in the SCB @{ */ /** \brief Structure type to access the System Control and ID Register not in the SCB. */ typedef struct { uint32_t RESERVED0[1U]; __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ } SCnSCB_Type; /* Interrupt Controller Type Register Definitions */ #define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ #define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ /*@} end of group CMSIS_SCnotSCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SysTick System Tick Timer (SysTick) \brief Type definitions for the System Timer Registers. @{ */ /** \brief Structure type to access the System Timer (SysTick). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; /* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ /* SysTick Calibration Register Definitions */ #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ /*@} end of group CMSIS_SysTick */ /** \ingroup CMSIS_core_register \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) \brief Type definitions for the Instrumentation Trace Macrocell (ITM) @{ */ /** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). */ typedef struct { __OM union { __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ uint32_t RESERVED0[864U]; __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ uint32_t RESERVED1[15U]; __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ uint32_t RESERVED2[15U]; __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ uint32_t RESERVED3[32U]; uint32_t RESERVED4[43U]; __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ uint32_t RESERVED5[1U]; __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ uint32_t RESERVED6[4U]; __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ } ITM_Type; /* ITM Stimulus Port Register Definitions */ #define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ #define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ #define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ #define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ /* ITM Trace Privilege Register Definitions */ #define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ #define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ /* ITM Trace Control Register Definitions */ #define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ #define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ #define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ #define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ #define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ #define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ #define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ #define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ #define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ #define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ #define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ #define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ #define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ #define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ #define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ #define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ #define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ #define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ #define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ #define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ /* ITM Lock Status Register Definitions */ #define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ #define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ #define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ #define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ #define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ #define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ /*@}*/ /* end of group CMSIS_ITM */ /** \ingroup CMSIS_core_register \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) \brief Type definitions for the Data Watchpoint and Trace (DWT) @{ */ /** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ uint32_t RESERVED1[1U]; __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ uint32_t RESERVED2[1U]; __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ uint32_t RESERVED3[1U]; __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ uint32_t RESERVED4[1U]; __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ uint32_t RESERVED5[1U]; __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ uint32_t RESERVED6[1U]; __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ uint32_t RESERVED7[1U]; __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ uint32_t RESERVED8[1U]; __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ uint32_t RESERVED9[1U]; __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ uint32_t RESERVED10[1U]; __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ uint32_t RESERVED11[1U]; __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ uint32_t RESERVED12[1U]; __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ uint32_t RESERVED13[1U]; __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ uint32_t RESERVED14[1U]; __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ uint32_t RESERVED15[1U]; __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ uint32_t RESERVED16[1U]; __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ uint32_t RESERVED17[1U]; __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ uint32_t RESERVED18[1U]; __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ uint32_t RESERVED19[1U]; __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ uint32_t RESERVED20[1U]; __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ uint32_t RESERVED21[1U]; __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ uint32_t RESERVED22[1U]; __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ uint32_t RESERVED23[1U]; __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ uint32_t RESERVED24[1U]; __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ uint32_t RESERVED25[1U]; __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ uint32_t RESERVED26[1U]; __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ uint32_t RESERVED27[1U]; __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ uint32_t RESERVED28[1U]; __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ uint32_t RESERVED29[1U]; __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ uint32_t RESERVED30[1U]; __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ uint32_t RESERVED31[1U]; __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ uint32_t RESERVED32[934U]; __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ uint32_t RESERVED33[1U]; __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ } DWT_Type; /* DWT Control Register Definitions */ #define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ #define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ #define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ #define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ #define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ #define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ #define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ #define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ #define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ #define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ #define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ #define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ #define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ #define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ #define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ #define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ #define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ #define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ #define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ #define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ #define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ #define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ #define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ #define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ #define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ #define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ #define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ #define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ #define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ #define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ #define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ #define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ #define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ #define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ #define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ #define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ #define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ #define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ /* DWT CPI Count Register Definitions */ #define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ #define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ /* DWT Exception Overhead Count Register Definitions */ #define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ #define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ /* DWT Sleep Count Register Definitions */ #define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ #define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ /* DWT LSU Count Register Definitions */ #define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ #define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ /* DWT Folded-instruction Count Register Definitions */ #define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ #define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ /* DWT Comparator Function Register Definitions */ #define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ #define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ #define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ #define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ #define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ #define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ #define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ #define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ #define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ #define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ /*@}*/ /* end of group CMSIS_DWT */ /** \ingroup CMSIS_core_register \defgroup CMSIS_TPI Trace Port Interface (TPI) \brief Type definitions for the Trace Port Interface (TPI) @{ */ /** \brief Structure type to access the Trace Port Interface Register (TPI). */ typedef struct { __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ uint32_t RESERVED1[55U]; __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ uint32_t RESERVED2[131U]; __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ uint32_t RESERVED3[809U]; __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ uint32_t RESERVED4[4U]; __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ } TPI_Type; /* TPI Asynchronous Clock Prescaler Register Definitions */ #define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ #define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ /* TPI Selected Pin Protocol Register Definitions */ #define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ #define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ /* TPI Formatter and Flush Status Register Definitions */ #define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ #define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ #define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ #define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ #define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ #define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ #define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ #define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ /* TPI Formatter and Flush Control Register Definitions */ #define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ #define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ #define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ #define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ #define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ #define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ /* TPI Periodic Synchronization Control Register Definitions */ #define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ #define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ /* TPI Software Lock Status Register Definitions */ #define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ #define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ #define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ #define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ #define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ #define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ #define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ #define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ #define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ #define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ #define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ #define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ #define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ /* TPI DEVTYPE Register Definitions */ #define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ #define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ #define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ /*@}*/ /* end of group CMSIS_TPI */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) /** \ingroup CMSIS_core_register \defgroup CMSIS_MPU Memory Protection Unit (MPU) \brief Type definitions for the Memory Protection Unit (MPU) @{ */ /** \brief Structure type to access the Memory Protection Unit (MPU). */ typedef struct { __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ uint32_t RESERVED0[1]; union { __IOM uint32_t MAIR[2]; struct { __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ }; }; } MPU_Type; #define MPU_TYPE_RALIASES 4U /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ #define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ #define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ #define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ #define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ /* MPU Control Register Definitions */ #define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ #define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ #define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ #define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ #define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ #define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ /* MPU Region Number Register Definitions */ #define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ #define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ /* MPU Region Base Address Register Definitions */ #define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ #define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ #define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ #define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ #define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ #define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ #define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ #define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ /* MPU Region Limit Address Register Definitions */ #define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ #define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ #define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ #define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ #define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ #define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ /* MPU Memory Attribute Indirection Register 0 Definitions */ #define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ #define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ #define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ #define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ #define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ #define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ #define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ #define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ /* MPU Memory Attribute Indirection Register 1 Definitions */ #define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ #define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ #define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ #define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ #define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ #define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ #define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ #define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ /*@} end of group CMSIS_MPU */ #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \ingroup CMSIS_core_register \defgroup CMSIS_SAU Security Attribution Unit (SAU) \brief Type definitions for the Security Attribution Unit (SAU) @{ */ /** \brief Structure type to access the Security Attribution Unit (SAU). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ #if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ #else uint32_t RESERVED0[3]; #endif __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ } SAU_Type; /* SAU Control Register Definitions */ #define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ #define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ #define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ #define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ /* SAU Type Register Definitions */ #define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ #define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ #if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) /* SAU Region Number Register Definitions */ #define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ #define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ /* SAU Region Base Address Register Definitions */ #define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ #define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ /* SAU Region Limit Address Register Definitions */ #define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ #define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ #define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ #define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ #define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ #define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ #endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ /* Secure Fault Status Register Definitions */ #define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ #define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ #define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ #define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ #define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ #define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ #define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ #define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ #define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ #define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ #define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ #define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ #define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ #define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ #define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ #define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ /*@} end of group CMSIS_SAU */ #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /** \ingroup CMSIS_core_register \defgroup CMSIS_FPU Floating Point Unit (FPU) \brief Type definitions for the Floating Point Unit (FPU) @{ */ /** \brief Structure type to access the Floating Point Unit (FPU). */ typedef struct { uint32_t RESERVED0[1U]; __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ } FPU_Type; /* Floating-Point Context Control Register Definitions */ #define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ #define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ #define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ #define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ #define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ #define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ #define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ #define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ #define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ #define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ #define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ #define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ #define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ #define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ #define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ #define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ #define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ #define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ #define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ #define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ #define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ #define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ #define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ #define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ #define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ #define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ #define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ #define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ #define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ #define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ #define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ #define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ #define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ #define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ /* Floating-Point Context Address Register Definitions */ #define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ #define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ /* Floating-Point Default Status Control Register Definitions */ #define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ #define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ #define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ #define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ #define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ #define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ #define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ #define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ /* Media and FP Feature Register 0 Definitions */ #define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ #define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ #define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ #define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ #define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ #define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ #define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ #define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ #define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ #define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ #define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ #define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ #define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ #define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ #define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ #define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ /* Media and FP Feature Register 1 Definitions */ #define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ #define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ #define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ #define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ #define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ #define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ #define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ #define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ /*@} end of group CMSIS_FPU */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) \brief Type definitions for the Core Debug Registers @{ */ /** \brief Structure type to access the Core Debug Register (CoreDebug). */ typedef struct { __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ uint32_t RESERVED4[1U]; __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ } CoreDebug_Type; /* Debug Halting Control and Status Register Definitions */ #define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ #define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ #define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ #define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ #define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ #define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ #define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ #define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ #define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ #define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ #define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ #define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ #define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ #define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ #define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ #define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ #define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ #define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ #define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ #define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ #define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ #define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ #define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ #define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ /* Debug Core Register Selector Register Definitions */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ #define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ /* Debug Exception and Monitor Control Register Definitions */ #define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ #define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ #define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ #define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ #define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ #define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ #define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ #define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ #define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ #define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ #define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ #define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ #define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ #define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ #define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ #define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ #define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ #define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ #define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ #define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ #define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ #define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ #define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ #define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ #define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ #define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ /* Debug Authentication Control Register Definitions */ #define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ #define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ #define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ #define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ #define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ #define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ #define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ #define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ /* Debug Security Control and Status Register Definitions */ #define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ #define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ #define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ #define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ #define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ #define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ /*@} end of group CMSIS_CoreDebug */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_bitfield Core register bit field macros \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). @{ */ /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_base Core Definitions \brief Definitions for base addresses, unions, and structures. @{ */ /* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ #endif #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ #endif #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /*@} */ /******************************************************************************* * Hardware Abstraction Layer Core Function Interface contains: - Core NVIC Functions - Core SysTick Functions - Core Debug Functions - Core Register Access Functions ******************************************************************************/ /** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference */ /* ########################## NVIC functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_NVICFunctions NVIC Functions \brief Functions that manage interrupts and exceptions via the NVIC. @{ */ #ifdef CMSIS_NVIC_VIRTUAL #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" #endif #include CMSIS_NVIC_VIRTUAL_HEADER_FILE #else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ #define NVIC_GetActive __NVIC_GetActive #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ #ifdef CMSIS_VECTAB_VIRTUAL #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" #endif #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE #else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ #define NVIC_USER_IRQ_OFFSET 16 /* Special LR values for Secure/Non-Secure call handling and exception handling */ /* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ #define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ /* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ #define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ #define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ #define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ #define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ #define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ #define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ #define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ /* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ #define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ #else #define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ #endif /** \brief Set Priority Grouping \details Sets the priority grouping field using the required unlock sequence. The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Priority grouping field. */ __STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ reg_value = SCB->AIRCR; /* read old register configuration */ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB->AIRCR = reg_value; } /** \brief Get Priority Grouping \details Reads the priority grouping field from the NVIC Interrupt Controller. \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ __STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) { return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); } /** \brief Enable Interrupt \details Enables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { __COMPILER_BARRIER(); NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __COMPILER_BARRIER(); } } /** \brief Get Interrupt Enable status \details Returns a device specific interrupt enable status from the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt \details Disables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } } /** \brief Get Pending Interrupt \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt \details Sets the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt \details Clears the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Get Interrupt Target State \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure \return 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Target State \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Clear Interrupt Target State \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /** \brief Set Interrupt Priority \details Sets the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every processor exception. */ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } /** \brief Get Interrupt Priority \details Reads the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } /** \brief Encode Priority \details Encodes the priority for an interrupt with the given priority group, preemptive priority value, and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Used priority group. \param [in] PreemptPriority Preemptive priority value (starting from 0). \param [in] SubPriority Subpriority value (starting from 0). \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). */ __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); return ( ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) ); } /** \brief Decode Priority \details Decodes an interrupt priority value with a given priority group to preemptive priority value and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). \param [in] PriorityGroup Used priority group. \param [out] pPreemptPriority Preemptive priority value (starting from 0). \param [out] pSubPriority Subpriority value (starting from 0). */ __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); } /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. VTOR must been relocated to SRAM before. \param [in] IRQn Interrupt number \param [in] vector Address of interrupt handler function */ __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { uint32_t *vectors = (uint32_t *)SCB->VTOR; vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; __DSB(); } /** \brief Get Interrupt Vector \details Reads an interrupt vector from interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Address of interrupt handler function */ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) { uint32_t *vectors = (uint32_t *)SCB->VTOR; return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; } /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ __DSB(); /* Ensure completion of memory access */ for(;;) /* wait until reset */ { __NOP(); } } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Set Priority Grouping (non-secure) \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Priority grouping field. */ __STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ reg_value = SCB_NS->AIRCR; /* read old register configuration */ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB_NS->AIRCR = reg_value; } /** \brief Get Priority Grouping (non-secure) \details Reads the priority grouping field from the non-secure NVIC when in secure state. \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ __STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) { return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); } /** \brief Enable Interrupt (non-secure) \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Interrupt Enable status (non-secure) \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt (non-secure) \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Pending Interrupt (non-secure) \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt (non-secure) \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt (non-secure) \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt (non-secure) \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Priority (non-secure) \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every non-secure processor exception. */ __STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } /** \brief Get Interrupt Priority (non-secure) \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } #endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ /*@} end of CMSIS_Core_NVICFunctions */ /* ########################## MPU functions #################################### */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #include "mpu_armv8.h" #endif /* ########################## FPU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_FpuFunctions FPU Functions \brief Function that provides FPU type. @{ */ /** \brief get FPU type \details returns the FPU type \returns - \b 0: No FPU - \b 1: Single precision FPU - \b 2: Double + Single precision FPU */ __STATIC_INLINE uint32_t SCB_GetFPUType(void) { uint32_t mvfr0; mvfr0 = FPU->MVFR0; if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) { return 2U; /* Double + Single precision FPU */ } else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) { return 1U; /* Single precision FPU */ } else { return 0U; /* No FPU */ } } /*@} end of CMSIS_Core_FpuFunctions */ /* ########################## SAU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SAUFunctions SAU Functions \brief Functions that configure the SAU. @{ */ #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Enable SAU \details Enables the Security Attribution Unit (SAU). */ __STATIC_INLINE void TZ_SAU_Enable(void) { SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); } /** \brief Disable SAU \details Disables the Security Attribution Unit (SAU). */ __STATIC_INLINE void TZ_SAU_Disable(void) { SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /*@} end of CMSIS_Core_SAUFunctions */ /* ################################## SysTick function ############################################ */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SysTickFunctions SysTick Functions \brief Functions that configure the System. @{ */ #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief System Tick Configuration (non-secure) \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function TZ_SysTick_Config_NS is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ #endif /*@} end of CMSIS_Core_SysTickFunctions */ /* ##################################### Debug In/Output function ########################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_core_DebugFunctions ITM Functions \brief Functions that access the ITM debug interface. @{ */ extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ #define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ /** \brief ITM Send Character \details Transmits a character via the ITM channel 0, and \li Just returns when no debugger is connected that has booked the output. \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. \param [in] ch Character to transmit. \returns Character to transmit. */ __STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) { if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ { while (ITM->PORT[0U].u32 == 0UL) { __NOP(); } ITM->PORT[0U].u8 = (uint8_t)ch; } return (ch); } /** \brief ITM Receive Character \details Inputs a character via the external variable \ref ITM_RxBuffer. \return Received character. \return -1 No character pending. */ __STATIC_INLINE int32_t ITM_ReceiveChar (void) { int32_t ch = -1; /* no character available */ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { ch = ITM_RxBuffer; ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ } return (ch); } /** \brief ITM Check Character \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. \return 0 No character available. \return 1 Character available. */ __STATIC_INLINE int32_t ITM_CheckChar (void) { if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { return (0); /* no character available */ } else { return (1); /* character available */ } } /*@} end of CMSIS_core_DebugFunctions */ #ifdef __cplusplus } #endif #endif /* __CORE_ARMV8MML_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ ================================================ FILE: 3rd_party/CMSIS/Include/core_cm0.h ================================================ /**************************************************************************//** * @file core_cm0.h * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File * @version V5.0.6 * @date 13. March 2019 ******************************************************************************/ /* * Copyright (c) 2009-2019 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_CM0_H_GENERIC #define __CORE_CM0_H_GENERIC #include #ifdef __cplusplus extern "C" { #endif /** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions CMSIS violates the following MISRA-C:2004 rules: \li Required Rule 8.5, object/function definition in header file.
Function definitions in header files are used to allow 'inlining'. \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
Unions are used for effective representation of core registers. \li Advisory Rule 19.7, Function-like macro defined.
Function-like macros are used to allow more efficient code. */ /******************************************************************************* * CMSIS definitions ******************************************************************************/ /** \ingroup Cortex_M0 @{ */ #include "cmsis_version.h" /* CMSIS CM0 definitions */ #define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ #define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ __CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (0U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all */ #define __FPU_USED 0U #if defined ( __CC_ARM ) #if defined __TARGET_FPU_VFP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined __ARM_FP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TASKING__ ) #if defined __FPU_VFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __CSMC__ ) #if ( __CSMC__ & 0x400U) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #endif #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ #ifdef __cplusplus } #endif #endif /* __CORE_CM0_H_GENERIC */ #ifndef __CMSIS_GENERIC #ifndef __CORE_CM0_H_DEPENDANT #define __CORE_CM0_H_DEPENDANT #ifdef __cplusplus extern "C" { #endif /* check device defines and use defaults */ #if defined __CHECK_DEVICE_DEFINES #ifndef __CM0_REV #define __CM0_REV 0x0000U #warning "__CM0_REV not defined in device header file; using default!" #endif #ifndef __NVIC_PRIO_BITS #define __NVIC_PRIO_BITS 2U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif #ifndef __Vendor_SysTickConfig #define __Vendor_SysTickConfig 0U #warning "__Vendor_SysTickConfig not defined in device header file; using default!" #endif #endif /* IO definitions (access restrictions to peripheral registers) */ /** \defgroup CMSIS_glob_defs CMSIS Global Defines IO Type Qualifiers are used \li to specify the access to peripheral variables. \li for automatic generation of peripheral register debug information. */ #ifdef __cplusplus #define __I volatile /*!< Defines 'read only' permissions */ #else #define __I volatile const /*!< Defines 'read only' permissions */ #endif #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */ /* following defines should be used for structure members */ #define __IM volatile const /*! Defines 'read only' structure member permissions */ #define __OM volatile /*! Defines 'write only' structure member permissions */ #define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group Cortex_M0 */ /******************************************************************************* * Register Abstraction Core Register contain: - Core Register - Core NVIC Register - Core SCB Register - Core SysTick Register ******************************************************************************/ /** \defgroup CMSIS_core_register Defines and Type Definitions \brief Type definitions and defines for Cortex-M processor based devices. */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CORE Status and Control Registers \brief Core Register type definitions. @{ */ /** \brief Union type to access the Application Program Status Register (APSR). */ typedef union { struct { uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } APSR_Type; /* APSR Register Definitions */ #define APSR_N_Pos 31U /*!< APSR: N Position */ #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ #define APSR_Z_Pos 30U /*!< APSR: Z Position */ #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ #define APSR_C_Pos 29U /*!< APSR: C Position */ #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ #define APSR_V_Pos 28U /*!< APSR: V Position */ #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ /** \brief Union type to access the Interrupt Program Status Register (IPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } IPSR_Type; /* IPSR Register Definitions */ #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ /** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } xPSR_Type; /* xPSR Register Definitions */ #define xPSR_N_Pos 31U /*!< xPSR: N Position */ #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ #define xPSR_C_Pos 29U /*!< xPSR: C Position */ #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ #define xPSR_V_Pos 28U /*!< xPSR: V Position */ #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ /** \brief Union type to access the Control Registers (CONTROL). */ typedef union { struct { uint32_t _reserved0:1; /*!< bit: 0 Reserved */ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } CONTROL_Type; /* CONTROL Register Definitions */ #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ /*@} end of group CMSIS_CORE */ /** \ingroup CMSIS_core_register \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) \brief Type definitions for the NVIC Registers @{ */ /** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). */ typedef struct { __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[31U]; __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ uint32_t RESERVED1[31U]; __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[31U]; __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ uint32_t RESERVED3[31U]; uint32_t RESERVED4[64U]; __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ } NVIC_Type; /*@} end of group CMSIS_NVIC */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCB System Control Block (SCB) \brief Type definitions for the System Control Block Registers @{ */ /** \brief Structure type to access the System Control Block (SCB). */ typedef struct { __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ uint32_t RESERVED0; __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ uint32_t RESERVED1; __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ } SCB_Type; /* SCB CPUID Register Definitions */ #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ /* SCB Interrupt Control State Register Definitions */ #define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ #define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ /* SCB Application Interrupt and Reset Control Register Definitions */ #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ /* SCB System Control Register Definitions */ #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ /* SCB Configuration Control Register Definitions */ #define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ #define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ /* SCB System Handler Control and State Register Definitions */ #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ /*@} end of group CMSIS_SCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SysTick System Tick Timer (SysTick) \brief Type definitions for the System Timer Registers. @{ */ /** \brief Structure type to access the System Timer (SysTick). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; /* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ /* SysTick Calibration Register Definitions */ #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ /*@} end of group CMSIS_SysTick */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. Therefore they are not covered by the Cortex-M0 header file. @{ */ /*@} end of group CMSIS_CoreDebug */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_bitfield Core register bit field macros \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). @{ */ /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_base Core Definitions \brief Definitions for base addresses, unions, and structures. @{ */ /* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ /*@} */ /******************************************************************************* * Hardware Abstraction Layer Core Function Interface contains: - Core NVIC Functions - Core SysTick Functions - Core Register Access Functions ******************************************************************************/ /** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference */ /* ########################## NVIC functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_NVICFunctions NVIC Functions \brief Functions that manage interrupts and exceptions via the NVIC. @{ */ #ifdef CMSIS_NVIC_VIRTUAL #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" #endif #include CMSIS_NVIC_VIRTUAL_HEADER_FILE #else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ /*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */ #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ #ifdef CMSIS_VECTAB_VIRTUAL #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" #endif #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE #else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ #define NVIC_USER_IRQ_OFFSET 16 /* The following EXC_RETURN values are saved the LR on exception entry */ #define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ #define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ #define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ /* Interrupt Priorities are WORD accessible only under Armv6-M */ /* The following MACROS handle generation of the register offset and byte masks */ #define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) #define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) #define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) #define __NVIC_SetPriorityGrouping(X) (void)(X) #define __NVIC_GetPriorityGrouping() (0U) /** \brief Enable Interrupt \details Enables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { __COMPILER_BARRIER(); NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __COMPILER_BARRIER(); } } /** \brief Get Interrupt Enable status \details Returns a device specific interrupt enable status from the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt \details Disables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } } /** \brief Get Pending Interrupt \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt \details Sets the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt \details Clears the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Set Interrupt Priority \details Sets the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every processor exception. */ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } else { SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } } /** \brief Get Interrupt Priority \details Reads the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } else { return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } } /** \brief Encode Priority \details Encodes the priority for an interrupt with the given priority group, preemptive priority value, and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Used priority group. \param [in] PreemptPriority Preemptive priority value (starting from 0). \param [in] SubPriority Subpriority value (starting from 0). \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). */ __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); return ( ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) ); } /** \brief Decode Priority \details Decodes an interrupt priority value with a given priority group to preemptive priority value and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). \param [in] PriorityGroup Used priority group. \param [out] pPreemptPriority Preemptive priority value (starting from 0). \param [out] pSubPriority Subpriority value (starting from 0). */ __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); } /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. Address 0 must be mapped to SRAM. \param [in] IRQn Interrupt number \param [in] vector Address of interrupt handler function */ __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { uint32_t vectors = 0x0U; (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; /* ARM Application Note 321 states that the M0 does not require the architectural barrier */ } /** \brief Get Interrupt Vector \details Reads an interrupt vector from interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Address of interrupt handler function */ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) { uint32_t vectors = 0x0U; return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); } /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk); __DSB(); /* Ensure completion of memory access */ for(;;) /* wait until reset */ { __NOP(); } } /*@} end of CMSIS_Core_NVICFunctions */ /* ########################## FPU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_FpuFunctions FPU Functions \brief Function that provides FPU type. @{ */ /** \brief get FPU type \details returns the FPU type \returns - \b 0: No FPU - \b 1: Single precision FPU - \b 2: Double + Single precision FPU */ __STATIC_INLINE uint32_t SCB_GetFPUType(void) { return 0U; /* No FPU */ } /*@} end of CMSIS_Core_FpuFunctions */ /* ################################## SysTick function ############################################ */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SysTickFunctions SysTick Functions \brief Functions that configure the System. @{ */ #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #endif /*@} end of CMSIS_Core_SysTickFunctions */ #ifdef __cplusplus } #endif #endif /* __CORE_CM0_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ ================================================ FILE: 3rd_party/CMSIS/Include/core_cm0plus.h ================================================ /**************************************************************************//** * @file core_cm0plus.h * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File * @version V5.0.7 * @date 13. March 2019 ******************************************************************************/ /* * Copyright (c) 2009-2019 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_CM0PLUS_H_GENERIC #define __CORE_CM0PLUS_H_GENERIC #include #ifdef __cplusplus extern "C" { #endif /** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions CMSIS violates the following MISRA-C:2004 rules: \li Required Rule 8.5, object/function definition in header file.
Function definitions in header files are used to allow 'inlining'. \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
Unions are used for effective representation of core registers. \li Advisory Rule 19.7, Function-like macro defined.
Function-like macros are used to allow more efficient code. */ /******************************************************************************* * CMSIS definitions ******************************************************************************/ /** \ingroup Cortex-M0+ @{ */ #include "cmsis_version.h" /* CMSIS CM0+ definitions */ #define __CM0PLUS_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ #define __CM0PLUS_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \ __CM0PLUS_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (0U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all */ #define __FPU_USED 0U #if defined ( __CC_ARM ) #if defined __TARGET_FPU_VFP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined __ARM_FP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TASKING__ ) #if defined __FPU_VFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __CSMC__ ) #if ( __CSMC__ & 0x400U) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #endif #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ #ifdef __cplusplus } #endif #endif /* __CORE_CM0PLUS_H_GENERIC */ #ifndef __CMSIS_GENERIC #ifndef __CORE_CM0PLUS_H_DEPENDANT #define __CORE_CM0PLUS_H_DEPENDANT #ifdef __cplusplus extern "C" { #endif /* check device defines and use defaults */ #if defined __CHECK_DEVICE_DEFINES #ifndef __CM0PLUS_REV #define __CM0PLUS_REV 0x0000U #warning "__CM0PLUS_REV not defined in device header file; using default!" #endif #ifndef __MPU_PRESENT #define __MPU_PRESENT 0U #warning "__MPU_PRESENT not defined in device header file; using default!" #endif #ifndef __VTOR_PRESENT #define __VTOR_PRESENT 0U #warning "__VTOR_PRESENT not defined in device header file; using default!" #endif #ifndef __NVIC_PRIO_BITS #define __NVIC_PRIO_BITS 2U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif #ifndef __Vendor_SysTickConfig #define __Vendor_SysTickConfig 0U #warning "__Vendor_SysTickConfig not defined in device header file; using default!" #endif #endif /* IO definitions (access restrictions to peripheral registers) */ /** \defgroup CMSIS_glob_defs CMSIS Global Defines IO Type Qualifiers are used \li to specify the access to peripheral variables. \li for automatic generation of peripheral register debug information. */ #ifdef __cplusplus #define __I volatile /*!< Defines 'read only' permissions */ #else #define __I volatile const /*!< Defines 'read only' permissions */ #endif #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */ /* following defines should be used for structure members */ #define __IM volatile const /*! Defines 'read only' structure member permissions */ #define __OM volatile /*! Defines 'write only' structure member permissions */ #define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group Cortex-M0+ */ /******************************************************************************* * Register Abstraction Core Register contain: - Core Register - Core NVIC Register - Core SCB Register - Core SysTick Register - Core MPU Register ******************************************************************************/ /** \defgroup CMSIS_core_register Defines and Type Definitions \brief Type definitions and defines for Cortex-M processor based devices. */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CORE Status and Control Registers \brief Core Register type definitions. @{ */ /** \brief Union type to access the Application Program Status Register (APSR). */ typedef union { struct { uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } APSR_Type; /* APSR Register Definitions */ #define APSR_N_Pos 31U /*!< APSR: N Position */ #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ #define APSR_Z_Pos 30U /*!< APSR: Z Position */ #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ #define APSR_C_Pos 29U /*!< APSR: C Position */ #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ #define APSR_V_Pos 28U /*!< APSR: V Position */ #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ /** \brief Union type to access the Interrupt Program Status Register (IPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } IPSR_Type; /* IPSR Register Definitions */ #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ /** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } xPSR_Type; /* xPSR Register Definitions */ #define xPSR_N_Pos 31U /*!< xPSR: N Position */ #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ #define xPSR_C_Pos 29U /*!< xPSR: C Position */ #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ #define xPSR_V_Pos 28U /*!< xPSR: V Position */ #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ /** \brief Union type to access the Control Registers (CONTROL). */ typedef union { struct { uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } CONTROL_Type; /* CONTROL Register Definitions */ #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ #define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ #define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ /*@} end of group CMSIS_CORE */ /** \ingroup CMSIS_core_register \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) \brief Type definitions for the NVIC Registers @{ */ /** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). */ typedef struct { __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[31U]; __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ uint32_t RESERVED1[31U]; __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[31U]; __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ uint32_t RESERVED3[31U]; uint32_t RESERVED4[64U]; __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ } NVIC_Type; /*@} end of group CMSIS_NVIC */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCB System Control Block (SCB) \brief Type definitions for the System Control Block Registers @{ */ /** \brief Structure type to access the System Control Block (SCB). */ typedef struct { __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ #if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ #else uint32_t RESERVED0; #endif __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ uint32_t RESERVED1; __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ } SCB_Type; /* SCB CPUID Register Definitions */ #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ /* SCB Interrupt Control State Register Definitions */ #define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ #define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ #if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) /* SCB Interrupt Control State Register Definitions */ #define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */ #define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ #endif /* SCB Application Interrupt and Reset Control Register Definitions */ #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ /* SCB System Control Register Definitions */ #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ /* SCB Configuration Control Register Definitions */ #define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ #define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ /* SCB System Handler Control and State Register Definitions */ #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ /*@} end of group CMSIS_SCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SysTick System Tick Timer (SysTick) \brief Type definitions for the System Timer Registers. @{ */ /** \brief Structure type to access the System Timer (SysTick). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; /* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ /* SysTick Calibration Register Definitions */ #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ /*@} end of group CMSIS_SysTick */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) /** \ingroup CMSIS_core_register \defgroup CMSIS_MPU Memory Protection Unit (MPU) \brief Type definitions for the Memory Protection Unit (MPU) @{ */ /** \brief Structure type to access the Memory Protection Unit (MPU). */ typedef struct { __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ } MPU_Type; #define MPU_TYPE_RALIASES 1U /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ #define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ #define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ #define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ #define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ /* MPU Control Register Definitions */ #define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ #define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ #define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ #define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ #define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ #define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ /* MPU Region Number Register Definitions */ #define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ #define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ /* MPU Region Base Address Register Definitions */ #define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ #define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ #define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ #define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ #define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ #define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ /* MPU Region Attribute and Size Register Definitions */ #define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ #define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ #define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ #define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ #define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ #define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ #define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ #define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ #define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ #define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ #define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ #define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ #define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ #define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ #define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ #define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ #define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ #define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ #define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ #define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ /*@} end of group CMSIS_MPU */ #endif /** \ingroup CMSIS_core_register \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. Therefore they are not covered by the Cortex-M0+ header file. @{ */ /*@} end of group CMSIS_CoreDebug */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_bitfield Core register bit field macros \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). @{ */ /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_base Core Definitions \brief Definitions for base addresses, unions, and structures. @{ */ /* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ #endif /*@} */ /******************************************************************************* * Hardware Abstraction Layer Core Function Interface contains: - Core NVIC Functions - Core SysTick Functions - Core Register Access Functions ******************************************************************************/ /** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference */ /* ########################## NVIC functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_NVICFunctions NVIC Functions \brief Functions that manage interrupts and exceptions via the NVIC. @{ */ #ifdef CMSIS_NVIC_VIRTUAL #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" #endif #include CMSIS_NVIC_VIRTUAL_HEADER_FILE #else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ /*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0+ */ #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ #ifdef CMSIS_VECTAB_VIRTUAL #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" #endif #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE #else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ #define NVIC_USER_IRQ_OFFSET 16 /* The following EXC_RETURN values are saved the LR on exception entry */ #define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ #define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ #define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ /* Interrupt Priorities are WORD accessible only under Armv6-M */ /* The following MACROS handle generation of the register offset and byte masks */ #define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) #define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) #define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) #define __NVIC_SetPriorityGrouping(X) (void)(X) #define __NVIC_GetPriorityGrouping() (0U) /** \brief Enable Interrupt \details Enables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { __COMPILER_BARRIER(); NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __COMPILER_BARRIER(); } } /** \brief Get Interrupt Enable status \details Returns a device specific interrupt enable status from the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt \details Disables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } } /** \brief Get Pending Interrupt \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt \details Sets the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt \details Clears the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Set Interrupt Priority \details Sets the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every processor exception. */ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } else { SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } } /** \brief Get Interrupt Priority \details Reads the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } else { return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } } /** \brief Encode Priority \details Encodes the priority for an interrupt with the given priority group, preemptive priority value, and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Used priority group. \param [in] PreemptPriority Preemptive priority value (starting from 0). \param [in] SubPriority Subpriority value (starting from 0). \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). */ __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); return ( ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) ); } /** \brief Decode Priority \details Decodes an interrupt priority value with a given priority group to preemptive priority value and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). \param [in] PriorityGroup Used priority group. \param [out] pPreemptPriority Preemptive priority value (starting from 0). \param [out] pSubPriority Subpriority value (starting from 0). */ __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); } /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. VTOR must been relocated to SRAM before. If VTOR is not present address 0 must be mapped to SRAM. \param [in] IRQn Interrupt number \param [in] vector Address of interrupt handler function */ __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { #if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) uint32_t vectors = SCB->VTOR; #else uint32_t vectors = 0x0U; #endif (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; /* ARM Application Note 321 states that the M0+ does not require the architectural barrier */ } /** \brief Get Interrupt Vector \details Reads an interrupt vector from interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Address of interrupt handler function */ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) { #if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) uint32_t vectors = SCB->VTOR; #else uint32_t vectors = 0x0U; #endif return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); } /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk); __DSB(); /* Ensure completion of memory access */ for(;;) /* wait until reset */ { __NOP(); } } /*@} end of CMSIS_Core_NVICFunctions */ /* ########################## MPU functions #################################### */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #include "mpu_armv7.h" #endif /* ########################## FPU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_FpuFunctions FPU Functions \brief Function that provides FPU type. @{ */ /** \brief get FPU type \details returns the FPU type \returns - \b 0: No FPU - \b 1: Single precision FPU - \b 2: Double + Single precision FPU */ __STATIC_INLINE uint32_t SCB_GetFPUType(void) { return 0U; /* No FPU */ } /*@} end of CMSIS_Core_FpuFunctions */ /* ################################## SysTick function ############################################ */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SysTickFunctions SysTick Functions \brief Functions that configure the System. @{ */ #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #endif /*@} end of CMSIS_Core_SysTickFunctions */ #ifdef __cplusplus } #endif #endif /* __CORE_CM0PLUS_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ ================================================ FILE: 3rd_party/CMSIS/Include/core_cm1.h ================================================ /**************************************************************************//** * @file core_cm1.h * @brief CMSIS Cortex-M1 Core Peripheral Access Layer Header File * @version V1.0.1 * @date 12. November 2018 ******************************************************************************/ /* * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_CM1_H_GENERIC #define __CORE_CM1_H_GENERIC #include #ifdef __cplusplus extern "C" { #endif /** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions CMSIS violates the following MISRA-C:2004 rules: \li Required Rule 8.5, object/function definition in header file.
Function definitions in header files are used to allow 'inlining'. \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
Unions are used for effective representation of core registers. \li Advisory Rule 19.7, Function-like macro defined.
Function-like macros are used to allow more efficient code. */ /******************************************************************************* * CMSIS definitions ******************************************************************************/ /** \ingroup Cortex_M1 @{ */ #include "cmsis_version.h" /* CMSIS CM1 definitions */ #define __CM1_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ #define __CM1_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM1_CMSIS_VERSION ((__CM1_CMSIS_VERSION_MAIN << 16U) | \ __CM1_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (1U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all */ #define __FPU_USED 0U #if defined ( __CC_ARM ) #if defined __TARGET_FPU_VFP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined __ARM_FP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TASKING__ ) #if defined __FPU_VFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __CSMC__ ) #if ( __CSMC__ & 0x400U) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #endif #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ #ifdef __cplusplus } #endif #endif /* __CORE_CM1_H_GENERIC */ #ifndef __CMSIS_GENERIC #ifndef __CORE_CM1_H_DEPENDANT #define __CORE_CM1_H_DEPENDANT #ifdef __cplusplus extern "C" { #endif /* check device defines and use defaults */ #if defined __CHECK_DEVICE_DEFINES #ifndef __CM1_REV #define __CM1_REV 0x0100U #warning "__CM1_REV not defined in device header file; using default!" #endif #ifndef __NVIC_PRIO_BITS #define __NVIC_PRIO_BITS 2U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif #ifndef __Vendor_SysTickConfig #define __Vendor_SysTickConfig 0U #warning "__Vendor_SysTickConfig not defined in device header file; using default!" #endif #endif /* IO definitions (access restrictions to peripheral registers) */ /** \defgroup CMSIS_glob_defs CMSIS Global Defines IO Type Qualifiers are used \li to specify the access to peripheral variables. \li for automatic generation of peripheral register debug information. */ #ifdef __cplusplus #define __I volatile /*!< Defines 'read only' permissions */ #else #define __I volatile const /*!< Defines 'read only' permissions */ #endif #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */ /* following defines should be used for structure members */ #define __IM volatile const /*! Defines 'read only' structure member permissions */ #define __OM volatile /*! Defines 'write only' structure member permissions */ #define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group Cortex_M1 */ /******************************************************************************* * Register Abstraction Core Register contain: - Core Register - Core NVIC Register - Core SCB Register - Core SysTick Register ******************************************************************************/ /** \defgroup CMSIS_core_register Defines and Type Definitions \brief Type definitions and defines for Cortex-M processor based devices. */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CORE Status and Control Registers \brief Core Register type definitions. @{ */ /** \brief Union type to access the Application Program Status Register (APSR). */ typedef union { struct { uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } APSR_Type; /* APSR Register Definitions */ #define APSR_N_Pos 31U /*!< APSR: N Position */ #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ #define APSR_Z_Pos 30U /*!< APSR: Z Position */ #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ #define APSR_C_Pos 29U /*!< APSR: C Position */ #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ #define APSR_V_Pos 28U /*!< APSR: V Position */ #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ /** \brief Union type to access the Interrupt Program Status Register (IPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } IPSR_Type; /* IPSR Register Definitions */ #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ /** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } xPSR_Type; /* xPSR Register Definitions */ #define xPSR_N_Pos 31U /*!< xPSR: N Position */ #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ #define xPSR_C_Pos 29U /*!< xPSR: C Position */ #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ #define xPSR_V_Pos 28U /*!< xPSR: V Position */ #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ /** \brief Union type to access the Control Registers (CONTROL). */ typedef union { struct { uint32_t _reserved0:1; /*!< bit: 0 Reserved */ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } CONTROL_Type; /* CONTROL Register Definitions */ #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ /*@} end of group CMSIS_CORE */ /** \ingroup CMSIS_core_register \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) \brief Type definitions for the NVIC Registers @{ */ /** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). */ typedef struct { __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[31U]; __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ uint32_t RSERVED1[31U]; __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[31U]; __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ uint32_t RESERVED3[31U]; uint32_t RESERVED4[64U]; __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ } NVIC_Type; /*@} end of group CMSIS_NVIC */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCB System Control Block (SCB) \brief Type definitions for the System Control Block Registers @{ */ /** \brief Structure type to access the System Control Block (SCB). */ typedef struct { __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ uint32_t RESERVED0; __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ uint32_t RESERVED1; __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ } SCB_Type; /* SCB CPUID Register Definitions */ #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ /* SCB Interrupt Control State Register Definitions */ #define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ #define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ /* SCB Application Interrupt and Reset Control Register Definitions */ #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ /* SCB System Control Register Definitions */ #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ /* SCB Configuration Control Register Definitions */ #define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ #define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ /* SCB System Handler Control and State Register Definitions */ #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ /*@} end of group CMSIS_SCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) \brief Type definitions for the System Control and ID Register not in the SCB @{ */ /** \brief Structure type to access the System Control and ID Register not in the SCB. */ typedef struct { uint32_t RESERVED0[2U]; __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ } SCnSCB_Type; /* Auxiliary Control Register Definitions */ #define SCnSCB_ACTLR_ITCMUAEN_Pos 4U /*!< ACTLR: Instruction TCM Upper Alias Enable Position */ #define SCnSCB_ACTLR_ITCMUAEN_Msk (1UL << SCnSCB_ACTLR_ITCMUAEN_Pos) /*!< ACTLR: Instruction TCM Upper Alias Enable Mask */ #define SCnSCB_ACTLR_ITCMLAEN_Pos 3U /*!< ACTLR: Instruction TCM Lower Alias Enable Position */ #define SCnSCB_ACTLR_ITCMLAEN_Msk (1UL << SCnSCB_ACTLR_ITCMLAEN_Pos) /*!< ACTLR: Instruction TCM Lower Alias Enable Mask */ /*@} end of group CMSIS_SCnotSCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SysTick System Tick Timer (SysTick) \brief Type definitions for the System Timer Registers. @{ */ /** \brief Structure type to access the System Timer (SysTick). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; /* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ /* SysTick Calibration Register Definitions */ #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ /*@} end of group CMSIS_SysTick */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) \brief Cortex-M1 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. Therefore they are not covered by the Cortex-M1 header file. @{ */ /*@} end of group CMSIS_CoreDebug */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_bitfield Core register bit field macros \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). @{ */ /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_base Core Definitions \brief Definitions for base addresses, unions, and structures. @{ */ /* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ /*@} */ /******************************************************************************* * Hardware Abstraction Layer Core Function Interface contains: - Core NVIC Functions - Core SysTick Functions - Core Register Access Functions ******************************************************************************/ /** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference */ /* ########################## NVIC functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_NVICFunctions NVIC Functions \brief Functions that manage interrupts and exceptions via the NVIC. @{ */ #ifdef CMSIS_NVIC_VIRTUAL #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" #endif #include CMSIS_NVIC_VIRTUAL_HEADER_FILE #else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ /*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M1 */ #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ #ifdef CMSIS_VECTAB_VIRTUAL #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" #endif #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE #else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ #define NVIC_USER_IRQ_OFFSET 16 /* The following EXC_RETURN values are saved the LR on exception entry */ #define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ #define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ #define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ /* Interrupt Priorities are WORD accessible only under Armv6-M */ /* The following MACROS handle generation of the register offset and byte masks */ #define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) #define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) #define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) #define __NVIC_SetPriorityGrouping(X) (void)(X) #define __NVIC_GetPriorityGrouping() (0U) /** \brief Enable Interrupt \details Enables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { __COMPILER_BARRIER(); NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __COMPILER_BARRIER(); } } /** \brief Get Interrupt Enable status \details Returns a device specific interrupt enable status from the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt \details Disables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } } /** \brief Get Pending Interrupt \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt \details Sets the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt \details Clears the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Set Interrupt Priority \details Sets the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every processor exception. */ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } else { SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } } /** \brief Get Interrupt Priority \details Reads the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } else { return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } } /** \brief Encode Priority \details Encodes the priority for an interrupt with the given priority group, preemptive priority value, and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Used priority group. \param [in] PreemptPriority Preemptive priority value (starting from 0). \param [in] SubPriority Subpriority value (starting from 0). \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). */ __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); return ( ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) ); } /** \brief Decode Priority \details Decodes an interrupt priority value with a given priority group to preemptive priority value and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). \param [in] PriorityGroup Used priority group. \param [out] pPreemptPriority Preemptive priority value (starting from 0). \param [out] pSubPriority Subpriority value (starting from 0). */ __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); } /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. Address 0 must be mapped to SRAM. \param [in] IRQn Interrupt number \param [in] vector Address of interrupt handler function */ __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { uint32_t *vectors = (uint32_t *)0x0U; vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; /* ARM Application Note 321 states that the M1 does not require the architectural barrier */ } /** \brief Get Interrupt Vector \details Reads an interrupt vector from interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Address of interrupt handler function */ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) { uint32_t *vectors = (uint32_t *)0x0U; return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; } /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk); __DSB(); /* Ensure completion of memory access */ for(;;) /* wait until reset */ { __NOP(); } } /*@} end of CMSIS_Core_NVICFunctions */ /* ########################## FPU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_FpuFunctions FPU Functions \brief Function that provides FPU type. @{ */ /** \brief get FPU type \details returns the FPU type \returns - \b 0: No FPU - \b 1: Single precision FPU - \b 2: Double + Single precision FPU */ __STATIC_INLINE uint32_t SCB_GetFPUType(void) { return 0U; /* No FPU */ } /*@} end of CMSIS_Core_FpuFunctions */ /* ################################## SysTick function ############################################ */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SysTickFunctions SysTick Functions \brief Functions that configure the System. @{ */ #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #endif /*@} end of CMSIS_Core_SysTickFunctions */ #ifdef __cplusplus } #endif #endif /* __CORE_CM1_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ ================================================ FILE: 3rd_party/CMSIS/Include/core_cm23.h ================================================ /**************************************************************************//** * @file core_cm23.h * @brief CMSIS Cortex-M23 Core Peripheral Access Layer Header File * @version V5.0.8 * @date 12. November 2018 ******************************************************************************/ /* * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_CM23_H_GENERIC #define __CORE_CM23_H_GENERIC #include #ifdef __cplusplus extern "C" { #endif /** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions CMSIS violates the following MISRA-C:2004 rules: \li Required Rule 8.5, object/function definition in header file.
Function definitions in header files are used to allow 'inlining'. \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
Unions are used for effective representation of core registers. \li Advisory Rule 19.7, Function-like macro defined.
Function-like macros are used to allow more efficient code. */ /******************************************************************************* * CMSIS definitions ******************************************************************************/ /** \ingroup Cortex_M23 @{ */ #include "cmsis_version.h" /* CMSIS definitions */ #define __CM23_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ #define __CM23_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM23_CMSIS_VERSION ((__CM23_CMSIS_VERSION_MAIN << 16U) | \ __CM23_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (23U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all */ #define __FPU_USED 0U #if defined ( __CC_ARM ) #if defined __TARGET_FPU_VFP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined __ARM_FP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TASKING__ ) #if defined __FPU_VFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __CSMC__ ) #if ( __CSMC__ & 0x400U) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #endif #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ #ifdef __cplusplus } #endif #endif /* __CORE_CM23_H_GENERIC */ #ifndef __CMSIS_GENERIC #ifndef __CORE_CM23_H_DEPENDANT #define __CORE_CM23_H_DEPENDANT #ifdef __cplusplus extern "C" { #endif /* check device defines and use defaults */ #if defined __CHECK_DEVICE_DEFINES #ifndef __CM23_REV #define __CM23_REV 0x0000U #warning "__CM23_REV not defined in device header file; using default!" #endif #ifndef __FPU_PRESENT #define __FPU_PRESENT 0U #warning "__FPU_PRESENT not defined in device header file; using default!" #endif #ifndef __MPU_PRESENT #define __MPU_PRESENT 0U #warning "__MPU_PRESENT not defined in device header file; using default!" #endif #ifndef __SAUREGION_PRESENT #define __SAUREGION_PRESENT 0U #warning "__SAUREGION_PRESENT not defined in device header file; using default!" #endif #ifndef __VTOR_PRESENT #define __VTOR_PRESENT 0U #warning "__VTOR_PRESENT not defined in device header file; using default!" #endif #ifndef __NVIC_PRIO_BITS #define __NVIC_PRIO_BITS 2U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif #ifndef __Vendor_SysTickConfig #define __Vendor_SysTickConfig 0U #warning "__Vendor_SysTickConfig not defined in device header file; using default!" #endif #ifndef __ETM_PRESENT #define __ETM_PRESENT 0U #warning "__ETM_PRESENT not defined in device header file; using default!" #endif #ifndef __MTB_PRESENT #define __MTB_PRESENT 0U #warning "__MTB_PRESENT not defined in device header file; using default!" #endif #endif /* IO definitions (access restrictions to peripheral registers) */ /** \defgroup CMSIS_glob_defs CMSIS Global Defines IO Type Qualifiers are used \li to specify the access to peripheral variables. \li for automatic generation of peripheral register debug information. */ #ifdef __cplusplus #define __I volatile /*!< Defines 'read only' permissions */ #else #define __I volatile const /*!< Defines 'read only' permissions */ #endif #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */ /* following defines should be used for structure members */ #define __IM volatile const /*! Defines 'read only' structure member permissions */ #define __OM volatile /*! Defines 'write only' structure member permissions */ #define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group Cortex_M23 */ /******************************************************************************* * Register Abstraction Core Register contain: - Core Register - Core NVIC Register - Core SCB Register - Core SysTick Register - Core Debug Register - Core MPU Register - Core SAU Register ******************************************************************************/ /** \defgroup CMSIS_core_register Defines and Type Definitions \brief Type definitions and defines for Cortex-M processor based devices. */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CORE Status and Control Registers \brief Core Register type definitions. @{ */ /** \brief Union type to access the Application Program Status Register (APSR). */ typedef union { struct { uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } APSR_Type; /* APSR Register Definitions */ #define APSR_N_Pos 31U /*!< APSR: N Position */ #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ #define APSR_Z_Pos 30U /*!< APSR: Z Position */ #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ #define APSR_C_Pos 29U /*!< APSR: C Position */ #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ #define APSR_V_Pos 28U /*!< APSR: V Position */ #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ /** \brief Union type to access the Interrupt Program Status Register (IPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } IPSR_Type; /* IPSR Register Definitions */ #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ /** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } xPSR_Type; /* xPSR Register Definitions */ #define xPSR_N_Pos 31U /*!< xPSR: N Position */ #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ #define xPSR_C_Pos 29U /*!< xPSR: C Position */ #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ #define xPSR_V_Pos 28U /*!< xPSR: V Position */ #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ /** \brief Union type to access the Control Registers (CONTROL). */ typedef union { struct { uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } CONTROL_Type; /* CONTROL Register Definitions */ #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ #define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ #define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ /*@} end of group CMSIS_CORE */ /** \ingroup CMSIS_core_register \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) \brief Type definitions for the NVIC Registers @{ */ /** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). */ typedef struct { __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[16U]; __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ uint32_t RSERVED1[16U]; __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[16U]; __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ uint32_t RESERVED3[16U]; __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ uint32_t RESERVED4[16U]; __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ uint32_t RESERVED5[16U]; __IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ } NVIC_Type; /*@} end of group CMSIS_NVIC */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCB System Control Block (SCB) \brief Type definitions for the System Control Block Registers @{ */ /** \brief Structure type to access the System Control Block (SCB). */ typedef struct { __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ #if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ #else uint32_t RESERVED0; #endif __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ uint32_t RESERVED1; __IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ } SCB_Type; /* SCB CPUID Register Definitions */ #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ /* SCB Interrupt Control State Register Definitions */ #define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ #define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ #define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ #define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ #define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ #define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ #define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ #define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ #define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ #define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ #if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) /* SCB Vector Table Offset Register Definitions */ #define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ #define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ #endif /* SCB Application Interrupt and Reset Control Register Definitions */ #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ #define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ #define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ #define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ #define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ #define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ #define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ /* SCB System Control Register Definitions */ #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ #define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ #define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ /* SCB Configuration Control Register Definitions */ #define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ #define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ #define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ #define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ #define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ #define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ #define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ #define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ #define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ #define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ #define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ #define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ #define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ #define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ /* SCB System Handler Control and State Register Definitions */ #define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ #define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ #define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ #define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ #define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ #define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ #define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ #define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ #define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ #define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ #define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ #define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ /*@} end of group CMSIS_SCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SysTick System Tick Timer (SysTick) \brief Type definitions for the System Timer Registers. @{ */ /** \brief Structure type to access the System Timer (SysTick). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; /* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ /* SysTick Calibration Register Definitions */ #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ /*@} end of group CMSIS_SysTick */ /** \ingroup CMSIS_core_register \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) \brief Type definitions for the Data Watchpoint and Trace (DWT) @{ */ /** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ uint32_t RESERVED0[6U]; __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ uint32_t RESERVED1[1U]; __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ uint32_t RESERVED2[1U]; __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ uint32_t RESERVED3[1U]; __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ uint32_t RESERVED4[1U]; __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ uint32_t RESERVED5[1U]; __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ uint32_t RESERVED6[1U]; __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ uint32_t RESERVED7[1U]; __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ uint32_t RESERVED8[1U]; __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ uint32_t RESERVED9[1U]; __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ uint32_t RESERVED10[1U]; __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ uint32_t RESERVED11[1U]; __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ uint32_t RESERVED12[1U]; __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ uint32_t RESERVED13[1U]; __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ uint32_t RESERVED14[1U]; __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ uint32_t RESERVED15[1U]; __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ uint32_t RESERVED16[1U]; __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ uint32_t RESERVED17[1U]; __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ uint32_t RESERVED18[1U]; __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ uint32_t RESERVED19[1U]; __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ uint32_t RESERVED20[1U]; __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ uint32_t RESERVED21[1U]; __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ uint32_t RESERVED22[1U]; __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ uint32_t RESERVED23[1U]; __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ uint32_t RESERVED24[1U]; __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ uint32_t RESERVED25[1U]; __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ uint32_t RESERVED26[1U]; __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ uint32_t RESERVED27[1U]; __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ uint32_t RESERVED28[1U]; __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ uint32_t RESERVED29[1U]; __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ uint32_t RESERVED30[1U]; __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ uint32_t RESERVED31[1U]; __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ } DWT_Type; /* DWT Control Register Definitions */ #define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ #define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ #define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ #define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ #define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ #define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ #define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ #define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ #define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ #define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ /* DWT Comparator Function Register Definitions */ #define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ #define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ #define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ #define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ #define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ #define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ #define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ #define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ #define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ #define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ /*@}*/ /* end of group CMSIS_DWT */ /** \ingroup CMSIS_core_register \defgroup CMSIS_TPI Trace Port Interface (TPI) \brief Type definitions for the Trace Port Interface (TPI) @{ */ /** \brief Structure type to access the Trace Port Interface Register (TPI). */ typedef struct { __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ uint32_t RESERVED1[55U]; __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ uint32_t RESERVED2[131U]; __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ uint32_t RESERVED3[759U]; __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ uint32_t RESERVED4[1U]; __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ uint32_t RESERVED5[39U]; __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ uint32_t RESERVED7[8U]; __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ } TPI_Type; /* TPI Asynchronous Clock Prescaler Register Definitions */ #define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ #define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ /* TPI Selected Pin Protocol Register Definitions */ #define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ #define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ /* TPI Formatter and Flush Status Register Definitions */ #define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ #define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ #define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ #define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ #define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ #define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ #define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ #define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ /* TPI Formatter and Flush Control Register Definitions */ #define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ #define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ #define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ #define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ #define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ #define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ /* TPI TRIGGER Register Definitions */ #define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ #define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ /* TPI Integration Test FIFO Test Data 0 Register Definitions */ #define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ #define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ #define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ #define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ #define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ #define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ #define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ #define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ #define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ #define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ #define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ #define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ #define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ #define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ /* TPI Integration Test ATB Control Register 2 Register Definitions */ #define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ #define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ #define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ #define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ #define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ #define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ #define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ #define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ /* TPI Integration Test FIFO Test Data 1 Register Definitions */ #define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ #define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ #define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ #define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ #define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ #define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ #define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ #define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ #define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ #define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ #define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ #define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ #define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ #define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ /* TPI Integration Test ATB Control Register 0 Definitions */ #define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ #define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ #define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ #define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ #define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ #define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ #define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ #define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ /* TPI Integration Mode Control Register Definitions */ #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ #define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ #define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ #define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ #define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ #define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ #define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ #define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ #define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ #define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ #define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ #define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ #define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ #define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ /*@}*/ /* end of group CMSIS_TPI */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) /** \ingroup CMSIS_core_register \defgroup CMSIS_MPU Memory Protection Unit (MPU) \brief Type definitions for the Memory Protection Unit (MPU) @{ */ /** \brief Structure type to access the Memory Protection Unit (MPU). */ typedef struct { __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ uint32_t RESERVED0[7U]; union { __IOM uint32_t MAIR[2]; struct { __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ }; }; } MPU_Type; #define MPU_TYPE_RALIASES 1U /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ #define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ #define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ #define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ #define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ /* MPU Control Register Definitions */ #define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ #define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ #define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ #define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ #define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ #define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ /* MPU Region Number Register Definitions */ #define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ #define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ /* MPU Region Base Address Register Definitions */ #define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ #define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ #define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ #define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ #define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ #define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ #define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ #define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ /* MPU Region Limit Address Register Definitions */ #define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ #define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ #define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ #define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ #define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */ #define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */ /* MPU Memory Attribute Indirection Register 0 Definitions */ #define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ #define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ #define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ #define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ #define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ #define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ #define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ #define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ /* MPU Memory Attribute Indirection Register 1 Definitions */ #define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ #define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ #define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ #define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ #define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ #define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ #define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ #define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ /*@} end of group CMSIS_MPU */ #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \ingroup CMSIS_core_register \defgroup CMSIS_SAU Security Attribution Unit (SAU) \brief Type definitions for the Security Attribution Unit (SAU) @{ */ /** \brief Structure type to access the Security Attribution Unit (SAU). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ #if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ #endif } SAU_Type; /* SAU Control Register Definitions */ #define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ #define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ #define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ #define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ /* SAU Type Register Definitions */ #define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ #define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ #if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) /* SAU Region Number Register Definitions */ #define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ #define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ /* SAU Region Base Address Register Definitions */ #define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ #define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ /* SAU Region Limit Address Register Definitions */ #define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ #define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ #define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ #define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ #define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ #define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ #endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ /*@} end of group CMSIS_SAU */ #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) \brief Type definitions for the Core Debug Registers @{ */ /** \brief Structure type to access the Core Debug Register (CoreDebug). */ typedef struct { __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ uint32_t RESERVED4[1U]; __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ } CoreDebug_Type; /* Debug Halting Control and Status Register Definitions */ #define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ #define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ #define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ #define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ #define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ #define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ #define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ #define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ #define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ #define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ #define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ #define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ #define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ #define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ #define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ #define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ #define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ #define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ #define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ #define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ #define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ #define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ /* Debug Core Register Selector Register Definitions */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ #define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ /* Debug Exception and Monitor Control Register */ #define CoreDebug_DEMCR_DWTENA_Pos 24U /*!< CoreDebug DEMCR: DWTENA Position */ #define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< CoreDebug DEMCR: DWTENA Mask */ #define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ #define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ #define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ #define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ /* Debug Authentication Control Register Definitions */ #define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ #define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ #define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ #define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ #define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ #define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ #define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ #define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ /* Debug Security Control and Status Register Definitions */ #define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ #define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ #define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ #define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ #define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ #define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ /*@} end of group CMSIS_CoreDebug */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_bitfield Core register bit field macros \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). @{ */ /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_base Core Definitions \brief Definitions for base addresses, unions, and structures. @{ */ /* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ #endif #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /*@} */ /******************************************************************************* * Hardware Abstraction Layer Core Function Interface contains: - Core NVIC Functions - Core SysTick Functions - Core Register Access Functions ******************************************************************************/ /** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference */ /* ########################## NVIC functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_NVICFunctions NVIC Functions \brief Functions that manage interrupts and exceptions via the NVIC. @{ */ #ifdef CMSIS_NVIC_VIRTUAL #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" #endif #include CMSIS_NVIC_VIRTUAL_HEADER_FILE #else /*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Cortex-M23 */ /*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Cortex-M23 */ #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ #define NVIC_GetActive __NVIC_GetActive #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ #ifdef CMSIS_VECTAB_VIRTUAL #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" #endif #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE #else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ #define NVIC_USER_IRQ_OFFSET 16 /* Special LR values for Secure/Non-Secure call handling and exception handling */ /* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ #define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ /* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ #define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ #define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ #define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ #define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ #define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ #define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ #define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ /* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ #define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ #else #define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ #endif /* Interrupt Priorities are WORD accessible only under Armv6-M */ /* The following MACROS handle generation of the register offset and byte masks */ #define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) #define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) #define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) #define __NVIC_SetPriorityGrouping(X) (void)(X) #define __NVIC_GetPriorityGrouping() (0U) /** \brief Enable Interrupt \details Enables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { __COMPILER_BARRIER(); NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __COMPILER_BARRIER(); } } /** \brief Get Interrupt Enable status \details Returns a device specific interrupt enable status from the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt \details Disables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } } /** \brief Get Pending Interrupt \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt \details Sets the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt \details Clears the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Get Interrupt Target State \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure \return 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Target State \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Clear Interrupt Target State \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /** \brief Set Interrupt Priority \details Sets the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every processor exception. */ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } else { SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } } /** \brief Get Interrupt Priority \details Reads the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } else { return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } } /** \brief Encode Priority \details Encodes the priority for an interrupt with the given priority group, preemptive priority value, and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Used priority group. \param [in] PreemptPriority Preemptive priority value (starting from 0). \param [in] SubPriority Subpriority value (starting from 0). \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). */ __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); return ( ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) ); } /** \brief Decode Priority \details Decodes an interrupt priority value with a given priority group to preemptive priority value and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). \param [in] PriorityGroup Used priority group. \param [out] pPreemptPriority Preemptive priority value (starting from 0). \param [out] pSubPriority Subpriority value (starting from 0). */ __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); } /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. VTOR must been relocated to SRAM before. If VTOR is not present address 0 must be mapped to SRAM. \param [in] IRQn Interrupt number \param [in] vector Address of interrupt handler function */ __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { #if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) uint32_t *vectors = (uint32_t *)SCB->VTOR; #else uint32_t *vectors = (uint32_t *)0x0U; #endif vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; __DSB(); } /** \brief Get Interrupt Vector \details Reads an interrupt vector from interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Address of interrupt handler function */ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) { #if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) uint32_t *vectors = (uint32_t *)SCB->VTOR; #else uint32_t *vectors = (uint32_t *)0x0U; #endif return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; } /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk); __DSB(); /* Ensure completion of memory access */ for(;;) /* wait until reset */ { __NOP(); } } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Enable Interrupt (non-secure) \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Interrupt Enable status (non-secure) \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt (non-secure) \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Pending Interrupt (non-secure) \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt (non-secure) \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt (non-secure) \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt (non-secure) \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Priority (non-secure) \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every non-secure processor exception. */ __STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } else { SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } } /** \brief Get Interrupt Priority (non-secure) \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } else { return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } } #endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ /*@} end of CMSIS_Core_NVICFunctions */ /* ########################## MPU functions #################################### */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #include "mpu_armv8.h" #endif /* ########################## FPU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_FpuFunctions FPU Functions \brief Function that provides FPU type. @{ */ /** \brief get FPU type \details returns the FPU type \returns - \b 0: No FPU - \b 1: Single precision FPU - \b 2: Double + Single precision FPU */ __STATIC_INLINE uint32_t SCB_GetFPUType(void) { return 0U; /* No FPU */ } /*@} end of CMSIS_Core_FpuFunctions */ /* ########################## SAU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SAUFunctions SAU Functions \brief Functions that configure the SAU. @{ */ #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Enable SAU \details Enables the Security Attribution Unit (SAU). */ __STATIC_INLINE void TZ_SAU_Enable(void) { SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); } /** \brief Disable SAU \details Disables the Security Attribution Unit (SAU). */ __STATIC_INLINE void TZ_SAU_Disable(void) { SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /*@} end of CMSIS_Core_SAUFunctions */ /* ################################## SysTick function ############################################ */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SysTickFunctions SysTick Functions \brief Functions that configure the System. @{ */ #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief System Tick Configuration (non-secure) \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function TZ_SysTick_Config_NS is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ #endif /*@} end of CMSIS_Core_SysTickFunctions */ #ifdef __cplusplus } #endif #endif /* __CORE_CM23_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ ================================================ FILE: 3rd_party/CMSIS/Include/core_cm3.h ================================================ /**************************************************************************//** * @file core_cm3.h * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File * @version V5.1.0 * @date 13. March 2019 ******************************************************************************/ /* * Copyright (c) 2009-2019 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_CM3_H_GENERIC #define __CORE_CM3_H_GENERIC #include #ifdef __cplusplus extern "C" { #endif /** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions CMSIS violates the following MISRA-C:2004 rules: \li Required Rule 8.5, object/function definition in header file.
Function definitions in header files are used to allow 'inlining'. \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
Unions are used for effective representation of core registers. \li Advisory Rule 19.7, Function-like macro defined.
Function-like macros are used to allow more efficient code. */ /******************************************************************************* * CMSIS definitions ******************************************************************************/ /** \ingroup Cortex_M3 @{ */ #include "cmsis_version.h" /* CMSIS CM3 definitions */ #define __CM3_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ #define __CM3_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \ __CM3_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (3U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all */ #define __FPU_USED 0U #if defined ( __CC_ARM ) #if defined __TARGET_FPU_VFP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined __ARM_FP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TASKING__ ) #if defined __FPU_VFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __CSMC__ ) #if ( __CSMC__ & 0x400U) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #endif #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ #ifdef __cplusplus } #endif #endif /* __CORE_CM3_H_GENERIC */ #ifndef __CMSIS_GENERIC #ifndef __CORE_CM3_H_DEPENDANT #define __CORE_CM3_H_DEPENDANT #ifdef __cplusplus extern "C" { #endif /* check device defines and use defaults */ #if defined __CHECK_DEVICE_DEFINES #ifndef __CM3_REV #define __CM3_REV 0x0200U #warning "__CM3_REV not defined in device header file; using default!" #endif #ifndef __MPU_PRESENT #define __MPU_PRESENT 0U #warning "__MPU_PRESENT not defined in device header file; using default!" #endif #ifndef __NVIC_PRIO_BITS #define __NVIC_PRIO_BITS 3U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif #ifndef __Vendor_SysTickConfig #define __Vendor_SysTickConfig 0U #warning "__Vendor_SysTickConfig not defined in device header file; using default!" #endif #endif /* IO definitions (access restrictions to peripheral registers) */ /** \defgroup CMSIS_glob_defs CMSIS Global Defines IO Type Qualifiers are used \li to specify the access to peripheral variables. \li for automatic generation of peripheral register debug information. */ #ifdef __cplusplus #define __I volatile /*!< Defines 'read only' permissions */ #else #define __I volatile const /*!< Defines 'read only' permissions */ #endif #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */ /* following defines should be used for structure members */ #define __IM volatile const /*! Defines 'read only' structure member permissions */ #define __OM volatile /*! Defines 'write only' structure member permissions */ #define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group Cortex_M3 */ /******************************************************************************* * Register Abstraction Core Register contain: - Core Register - Core NVIC Register - Core SCB Register - Core SysTick Register - Core Debug Register - Core MPU Register ******************************************************************************/ /** \defgroup CMSIS_core_register Defines and Type Definitions \brief Type definitions and defines for Cortex-M processor based devices. */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CORE Status and Control Registers \brief Core Register type definitions. @{ */ /** \brief Union type to access the Application Program Status Register (APSR). */ typedef union { struct { uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } APSR_Type; /* APSR Register Definitions */ #define APSR_N_Pos 31U /*!< APSR: N Position */ #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ #define APSR_Z_Pos 30U /*!< APSR: Z Position */ #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ #define APSR_C_Pos 29U /*!< APSR: C Position */ #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ #define APSR_V_Pos 28U /*!< APSR: V Position */ #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ #define APSR_Q_Pos 27U /*!< APSR: Q Position */ #define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ /** \brief Union type to access the Interrupt Program Status Register (IPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } IPSR_Type; /* IPSR Register Definitions */ #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ /** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:1; /*!< bit: 9 Reserved */ uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */ uint32_t T:1; /*!< bit: 24 Thumb bit */ uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } xPSR_Type; /* xPSR Register Definitions */ #define xPSR_N_Pos 31U /*!< xPSR: N Position */ #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ #define xPSR_C_Pos 29U /*!< xPSR: C Position */ #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ #define xPSR_V_Pos 28U /*!< xPSR: V Position */ #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ #define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ #define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ #define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ #define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ #define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ #define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ /** \brief Union type to access the Control Registers (CONTROL). */ typedef union { struct { uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } CONTROL_Type; /* CONTROL Register Definitions */ #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ #define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ #define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ /*@} end of group CMSIS_CORE */ /** \ingroup CMSIS_core_register \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) \brief Type definitions for the NVIC Registers @{ */ /** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). */ typedef struct { __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[24U]; __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ uint32_t RESERVED1[24U]; __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[24U]; __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ uint32_t RESERVED3[24U]; __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ uint32_t RESERVED4[56U]; __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ uint32_t RESERVED5[644U]; __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ } NVIC_Type; /* Software Triggered Interrupt Register Definitions */ #define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ #define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ /*@} end of group CMSIS_NVIC */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCB System Control Block (SCB) \brief Type definitions for the System Control Block Registers @{ */ /** \brief Structure type to access the System Control Block (SCB). */ typedef struct { __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ uint32_t RESERVED0[5U]; __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ } SCB_Type; /* SCB CPUID Register Definitions */ #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ /* SCB Interrupt Control State Register Definitions */ #define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ #define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ #define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ #define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ /* SCB Vector Table Offset Register Definitions */ #if defined (__CM3_REV) && (__CM3_REV < 0x0201U) /* core r2p1 */ #define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ #define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ #define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ #define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ #else #define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ #define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ #endif /* SCB Application Interrupt and Reset Control Register Definitions */ #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ #define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ #define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ #define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ #define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ /* SCB System Control Register Definitions */ #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ /* SCB Configuration Control Register Definitions */ #define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ #define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ #define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ #define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ #define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ #define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ #define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ #define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ #define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ #define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ /* SCB System Handler Control and State Register Definitions */ #define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ #define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ #define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ #define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ #define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ #define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ #define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ #define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ #define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ #define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ #define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ #define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ #define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ #define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ #define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ #define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ #define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ #define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ #define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ #define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ #define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ #define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ #define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ #define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ #define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ #define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ /* SCB Configurable Fault Status Register Definitions */ #define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ #define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ #define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ #define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ #define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ #define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ /* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ #define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ #define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ #define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ #define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ #define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ #define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ #define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ #define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ #define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ /* BusFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ #define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ #define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ #define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ #define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ #define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ #define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ #define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ #define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ #define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ #define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ #define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ /* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ #define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ #define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ #define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ #define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ #define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ #define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ #define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ #define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ #define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ #define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ #define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ /* SCB Hard Fault Status Register Definitions */ #define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ #define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ #define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ #define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ #define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ #define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ /* SCB Debug Fault Status Register Definitions */ #define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ #define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ #define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ #define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ #define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ #define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ #define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ #define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ #define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ #define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ /*@} end of group CMSIS_SCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) \brief Type definitions for the System Control and ID Register not in the SCB @{ */ /** \brief Structure type to access the System Control and ID Register not in the SCB. */ typedef struct { uint32_t RESERVED0[1U]; __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ #if defined (__CM3_REV) && (__CM3_REV >= 0x200U) __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ #else uint32_t RESERVED1[1U]; #endif } SCnSCB_Type; /* Interrupt Controller Type Register Definitions */ #define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ #define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ /* Auxiliary Control Register Definitions */ #if defined (__CM3_REV) && (__CM3_REV >= 0x200U) #define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ #define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ #define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ #define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ #define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ #define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ #define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ #define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ #define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ #define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ #endif /*@} end of group CMSIS_SCnotSCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SysTick System Tick Timer (SysTick) \brief Type definitions for the System Timer Registers. @{ */ /** \brief Structure type to access the System Timer (SysTick). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; /* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ /* SysTick Calibration Register Definitions */ #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ /*@} end of group CMSIS_SysTick */ /** \ingroup CMSIS_core_register \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) \brief Type definitions for the Instrumentation Trace Macrocell (ITM) @{ */ /** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). */ typedef struct { __OM union { __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ uint32_t RESERVED0[864U]; __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ uint32_t RESERVED1[15U]; __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ uint32_t RESERVED2[15U]; __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ uint32_t RESERVED3[32U]; uint32_t RESERVED4[43U]; __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ uint32_t RESERVED5[6U]; __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ } ITM_Type; /* ITM Trace Privilege Register Definitions */ #define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ #define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ /* ITM Trace Control Register Definitions */ #define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ #define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ #define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ #define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ #define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ #define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ #define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ #define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ #define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ #define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ #define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ #define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ #define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ #define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ #define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ #define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ #define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ #define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ /* ITM Lock Status Register Definitions */ #define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ #define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ #define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ #define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ #define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ #define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ /*@}*/ /* end of group CMSIS_ITM */ /** \ingroup CMSIS_core_register \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) \brief Type definitions for the Data Watchpoint and Trace (DWT) @{ */ /** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ uint32_t RESERVED0[1U]; __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ uint32_t RESERVED1[1U]; __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ uint32_t RESERVED2[1U]; __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ } DWT_Type; /* DWT Control Register Definitions */ #define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ #define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ #define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ #define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ #define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ #define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ #define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ #define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ #define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ #define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ #define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ #define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ #define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ #define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ #define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ #define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ #define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ #define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ #define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ #define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ #define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ #define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ #define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ #define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ #define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ #define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ #define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ #define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ #define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ #define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ #define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ #define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ #define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ #define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ #define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ #define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ /* DWT CPI Count Register Definitions */ #define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ #define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ /* DWT Exception Overhead Count Register Definitions */ #define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ #define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ /* DWT Sleep Count Register Definitions */ #define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ #define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ /* DWT LSU Count Register Definitions */ #define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ #define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ /* DWT Folded-instruction Count Register Definitions */ #define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ #define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ /* DWT Comparator Mask Register Definitions */ #define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ #define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ /* DWT Comparator Function Register Definitions */ #define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ #define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ #define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ #define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ #define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ #define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ #define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ #define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ #define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ #define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ #define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ #define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ #define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ #define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ #define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ #define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ #define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ #define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ /*@}*/ /* end of group CMSIS_DWT */ /** \ingroup CMSIS_core_register \defgroup CMSIS_TPI Trace Port Interface (TPI) \brief Type definitions for the Trace Port Interface (TPI) @{ */ /** \brief Structure type to access the Trace Port Interface Register (TPI). */ typedef struct { __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ uint32_t RESERVED1[55U]; __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ uint32_t RESERVED2[131U]; __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ uint32_t RESERVED3[759U]; __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ uint32_t RESERVED4[1U]; __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ uint32_t RESERVED5[39U]; __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ uint32_t RESERVED7[8U]; __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ } TPI_Type; /* TPI Asynchronous Clock Prescaler Register Definitions */ #define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ #define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ /* TPI Selected Pin Protocol Register Definitions */ #define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ #define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ /* TPI Formatter and Flush Status Register Definitions */ #define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ #define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ #define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ #define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ #define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ #define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ #define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ #define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ /* TPI Formatter and Flush Control Register Definitions */ #define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ #define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ #define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ #define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ /* TPI TRIGGER Register Definitions */ #define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ #define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ /* TPI Integration ETM Data Register Definitions (FIFO0) */ #define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ #define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ #define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ #define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ #define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ #define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ #define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ #define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ #define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ #define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ #define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ #define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ #define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ #define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ /* TPI ITATBCTR2 Register Definitions */ #define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ #define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ #define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ #define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ /* TPI Integration ITM Data Register Definitions (FIFO1) */ #define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ #define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ #define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ #define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ #define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ #define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ #define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ #define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ #define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ #define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ #define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ #define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ #define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ #define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ /* TPI ITATBCTR0 Register Definitions */ #define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ #define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ #define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ #define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ /* TPI Integration Mode Control Register Definitions */ #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ #define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ #define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ #define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ #define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ #define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ #define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ #define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ #define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ #define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ #define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ #define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ #define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ #define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ #define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ #define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ /*@}*/ /* end of group CMSIS_TPI */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) /** \ingroup CMSIS_core_register \defgroup CMSIS_MPU Memory Protection Unit (MPU) \brief Type definitions for the Memory Protection Unit (MPU) @{ */ /** \brief Structure type to access the Memory Protection Unit (MPU). */ typedef struct { __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ } MPU_Type; #define MPU_TYPE_RALIASES 4U /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ #define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ #define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ #define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ #define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ /* MPU Control Register Definitions */ #define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ #define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ #define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ #define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ #define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ #define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ /* MPU Region Number Register Definitions */ #define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ #define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ /* MPU Region Base Address Register Definitions */ #define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ #define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ #define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ #define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ #define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ #define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ /* MPU Region Attribute and Size Register Definitions */ #define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ #define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ #define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ #define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ #define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ #define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ #define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ #define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ #define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ #define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ #define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ #define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ #define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ #define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ #define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ #define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ #define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ #define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ #define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ #define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ /*@} end of group CMSIS_MPU */ #endif /** \ingroup CMSIS_core_register \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) \brief Type definitions for the Core Debug Registers @{ */ /** \brief Structure type to access the Core Debug Register (CoreDebug). */ typedef struct { __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ } CoreDebug_Type; /* Debug Halting Control and Status Register Definitions */ #define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ #define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ #define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ #define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ #define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ #define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ #define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ #define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ #define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ #define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ #define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ #define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ #define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ #define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ #define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ #define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ #define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ #define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ #define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ #define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ #define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ #define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ /* Debug Core Register Selector Register Definitions */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ #define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ /* Debug Exception and Monitor Control Register Definitions */ #define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ #define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ #define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ #define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ #define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ #define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ #define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ #define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ #define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ #define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ #define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ #define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ #define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ #define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ #define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ #define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ #define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ #define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ #define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ #define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ #define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ #define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ #define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ #define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ #define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ #define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ /*@} end of group CMSIS_CoreDebug */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_bitfield Core register bit field macros \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). @{ */ /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_base Core Definitions \brief Definitions for base addresses, unions, and structures. @{ */ /* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ #endif /*@} */ /******************************************************************************* * Hardware Abstraction Layer Core Function Interface contains: - Core NVIC Functions - Core SysTick Functions - Core Debug Functions - Core Register Access Functions ******************************************************************************/ /** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference */ /* ########################## NVIC functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_NVICFunctions NVIC Functions \brief Functions that manage interrupts and exceptions via the NVIC. @{ */ #ifdef CMSIS_NVIC_VIRTUAL #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" #endif #include CMSIS_NVIC_VIRTUAL_HEADER_FILE #else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ #define NVIC_GetActive __NVIC_GetActive #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ #ifdef CMSIS_VECTAB_VIRTUAL #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" #endif #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE #else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ #define NVIC_USER_IRQ_OFFSET 16 /* The following EXC_RETURN values are saved the LR on exception entry */ #define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ #define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ #define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ /** \brief Set Priority Grouping \details Sets the priority grouping field using the required unlock sequence. The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Priority grouping field. */ __STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ reg_value = SCB->AIRCR; /* read old register configuration */ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB->AIRCR = reg_value; } /** \brief Get Priority Grouping \details Reads the priority grouping field from the NVIC Interrupt Controller. \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ __STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) { return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); } /** \brief Enable Interrupt \details Enables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { __COMPILER_BARRIER(); NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __COMPILER_BARRIER(); } } /** \brief Get Interrupt Enable status \details Returns a device specific interrupt enable status from the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt \details Disables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } } /** \brief Get Pending Interrupt \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt \details Sets the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt \details Clears the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Priority \details Sets the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every processor exception. */ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } /** \brief Get Interrupt Priority \details Reads the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } /** \brief Encode Priority \details Encodes the priority for an interrupt with the given priority group, preemptive priority value, and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Used priority group. \param [in] PreemptPriority Preemptive priority value (starting from 0). \param [in] SubPriority Subpriority value (starting from 0). \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). */ __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); return ( ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) ); } /** \brief Decode Priority \details Decodes an interrupt priority value with a given priority group to preemptive priority value and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). \param [in] PriorityGroup Used priority group. \param [out] pPreemptPriority Preemptive priority value (starting from 0). \param [out] pSubPriority Subpriority value (starting from 0). */ __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); } /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. VTOR must been relocated to SRAM before. \param [in] IRQn Interrupt number \param [in] vector Address of interrupt handler function */ __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { uint32_t vectors = (uint32_t )SCB->VTOR; (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; /* ARM Application Note 321 states that the M3 does not require the architectural barrier */ } /** \brief Get Interrupt Vector \details Reads an interrupt vector from interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Address of interrupt handler function */ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) { uint32_t vectors = (uint32_t )SCB->VTOR; return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); } /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ __DSB(); /* Ensure completion of memory access */ for(;;) /* wait until reset */ { __NOP(); } } /*@} end of CMSIS_Core_NVICFunctions */ /* ########################## MPU functions #################################### */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #include "mpu_armv7.h" #endif /* ########################## FPU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_FpuFunctions FPU Functions \brief Function that provides FPU type. @{ */ /** \brief get FPU type \details returns the FPU type \returns - \b 0: No FPU - \b 1: Single precision FPU - \b 2: Double + Single precision FPU */ __STATIC_INLINE uint32_t SCB_GetFPUType(void) { return 0U; /* No FPU */ } /*@} end of CMSIS_Core_FpuFunctions */ /* ################################## SysTick function ############################################ */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SysTickFunctions SysTick Functions \brief Functions that configure the System. @{ */ #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #endif /*@} end of CMSIS_Core_SysTickFunctions */ /* ##################################### Debug In/Output function ########################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_core_DebugFunctions ITM Functions \brief Functions that access the ITM debug interface. @{ */ extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ #define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ /** \brief ITM Send Character \details Transmits a character via the ITM channel 0, and \li Just returns when no debugger is connected that has booked the output. \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. \param [in] ch Character to transmit. \returns Character to transmit. */ __STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) { if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ { while (ITM->PORT[0U].u32 == 0UL) { __NOP(); } ITM->PORT[0U].u8 = (uint8_t)ch; } return (ch); } /** \brief ITM Receive Character \details Inputs a character via the external variable \ref ITM_RxBuffer. \return Received character. \return -1 No character pending. */ __STATIC_INLINE int32_t ITM_ReceiveChar (void) { int32_t ch = -1; /* no character available */ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { ch = ITM_RxBuffer; ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ } return (ch); } /** \brief ITM Check Character \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. \return 0 No character available. \return 1 Character available. */ __STATIC_INLINE int32_t ITM_CheckChar (void) { if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { return (0); /* no character available */ } else { return (1); /* character available */ } } /*@} end of CMSIS_core_DebugFunctions */ #ifdef __cplusplus } #endif #endif /* __CORE_CM3_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ ================================================ FILE: 3rd_party/CMSIS/Include/core_cm33.h ================================================ /**************************************************************************//** * @file core_cm33.h * @brief CMSIS Cortex-M33 Core Peripheral Access Layer Header File * @version V5.1.0 * @date 12. November 2018 ******************************************************************************/ /* * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_CM33_H_GENERIC #define __CORE_CM33_H_GENERIC #include #ifdef __cplusplus extern "C" { #endif /** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions CMSIS violates the following MISRA-C:2004 rules: \li Required Rule 8.5, object/function definition in header file.
Function definitions in header files are used to allow 'inlining'. \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
Unions are used for effective representation of core registers. \li Advisory Rule 19.7, Function-like macro defined.
Function-like macros are used to allow more efficient code. */ /******************************************************************************* * CMSIS definitions ******************************************************************************/ /** \ingroup Cortex_M33 @{ */ #include "cmsis_version.h" /* CMSIS CM33 definitions */ #define __CM33_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ #define __CM33_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM33_CMSIS_VERSION ((__CM33_CMSIS_VERSION_MAIN << 16U) | \ __CM33_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (33U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. */ #if defined ( __CC_ARM ) #if defined (__TARGET_FPU_VFP) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined (__ARM_FP) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined ( __ICCARM__ ) #if defined (__ARMVFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined ( __TI_ARM__ ) #if defined (__TI_VFP_SUPPORT__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __TASKING__ ) #if defined (__FPU_VFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __CSMC__ ) #if ( __CSMC__ & 0x400U) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #endif #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ #ifdef __cplusplus } #endif #endif /* __CORE_CM33_H_GENERIC */ #ifndef __CMSIS_GENERIC #ifndef __CORE_CM33_H_DEPENDANT #define __CORE_CM33_H_DEPENDANT #ifdef __cplusplus extern "C" { #endif /* check device defines and use defaults */ #if defined __CHECK_DEVICE_DEFINES #ifndef __CM33_REV #define __CM33_REV 0x0000U #warning "__CM33_REV not defined in device header file; using default!" #endif #ifndef __FPU_PRESENT #define __FPU_PRESENT 0U #warning "__FPU_PRESENT not defined in device header file; using default!" #endif #ifndef __MPU_PRESENT #define __MPU_PRESENT 0U #warning "__MPU_PRESENT not defined in device header file; using default!" #endif #ifndef __SAUREGION_PRESENT #define __SAUREGION_PRESENT 0U #warning "__SAUREGION_PRESENT not defined in device header file; using default!" #endif #ifndef __DSP_PRESENT #define __DSP_PRESENT 0U #warning "__DSP_PRESENT not defined in device header file; using default!" #endif #ifndef __NVIC_PRIO_BITS #define __NVIC_PRIO_BITS 3U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif #ifndef __Vendor_SysTickConfig #define __Vendor_SysTickConfig 0U #warning "__Vendor_SysTickConfig not defined in device header file; using default!" #endif #endif /* IO definitions (access restrictions to peripheral registers) */ /** \defgroup CMSIS_glob_defs CMSIS Global Defines IO Type Qualifiers are used \li to specify the access to peripheral variables. \li for automatic generation of peripheral register debug information. */ #ifdef __cplusplus #define __I volatile /*!< Defines 'read only' permissions */ #else #define __I volatile const /*!< Defines 'read only' permissions */ #endif #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */ /* following defines should be used for structure members */ #define __IM volatile const /*! Defines 'read only' structure member permissions */ #define __OM volatile /*! Defines 'write only' structure member permissions */ #define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group Cortex_M33 */ /******************************************************************************* * Register Abstraction Core Register contain: - Core Register - Core NVIC Register - Core SCB Register - Core SysTick Register - Core Debug Register - Core MPU Register - Core SAU Register - Core FPU Register ******************************************************************************/ /** \defgroup CMSIS_core_register Defines and Type Definitions \brief Type definitions and defines for Cortex-M processor based devices. */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CORE Status and Control Registers \brief Core Register type definitions. @{ */ /** \brief Union type to access the Application Program Status Register (APSR). */ typedef union { struct { uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } APSR_Type; /* APSR Register Definitions */ #define APSR_N_Pos 31U /*!< APSR: N Position */ #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ #define APSR_Z_Pos 30U /*!< APSR: Z Position */ #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ #define APSR_C_Pos 29U /*!< APSR: C Position */ #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ #define APSR_V_Pos 28U /*!< APSR: V Position */ #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ #define APSR_Q_Pos 27U /*!< APSR: Q Position */ #define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ #define APSR_GE_Pos 16U /*!< APSR: GE Position */ #define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ /** \brief Union type to access the Interrupt Program Status Register (IPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } IPSR_Type; /* IPSR Register Definitions */ #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ /** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } xPSR_Type; /* xPSR Register Definitions */ #define xPSR_N_Pos 31U /*!< xPSR: N Position */ #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ #define xPSR_C_Pos 29U /*!< xPSR: C Position */ #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ #define xPSR_V_Pos 28U /*!< xPSR: V Position */ #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ #define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ #define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ #define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ #define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ #define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ #define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ /** \brief Union type to access the Control Registers (CONTROL). */ typedef union { struct { uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } CONTROL_Type; /* CONTROL Register Definitions */ #define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ #define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ #define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ #define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ #define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ #define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ /*@} end of group CMSIS_CORE */ /** \ingroup CMSIS_core_register \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) \brief Type definitions for the NVIC Registers @{ */ /** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). */ typedef struct { __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[16U]; __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ uint32_t RSERVED1[16U]; __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[16U]; __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ uint32_t RESERVED3[16U]; __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ uint32_t RESERVED4[16U]; __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ uint32_t RESERVED5[16U]; __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ uint32_t RESERVED6[580U]; __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ } NVIC_Type; /* Software Triggered Interrupt Register Definitions */ #define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ #define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ /*@} end of group CMSIS_NVIC */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCB System Control Block (SCB) \brief Type definitions for the System Control Block Registers @{ */ /** \brief Structure type to access the System Control Block (SCB). */ typedef struct { __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ uint32_t RESERVED3[92U]; __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ uint32_t RESERVED4[15U]; __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ uint32_t RESERVED5[1U]; __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ uint32_t RESERVED6[1U]; __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ } SCB_Type; /* SCB CPUID Register Definitions */ #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ /* SCB Interrupt Control State Register Definitions */ #define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ #define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ #define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ #define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ #define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ #define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ #define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ #define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ #define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ #define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ /* SCB Vector Table Offset Register Definitions */ #define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ #define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ /* SCB Application Interrupt and Reset Control Register Definitions */ #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ #define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ #define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ #define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ #define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ #define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ #define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ #define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ #define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ /* SCB System Control Register Definitions */ #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ #define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ #define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ /* SCB Configuration Control Register Definitions */ #define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ #define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ #define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ #define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ #define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ #define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ #define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ #define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ #define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ #define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ #define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ #define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ #define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ #define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ /* SCB System Handler Control and State Register Definitions */ #define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ #define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ #define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ #define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ #define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ #define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ #define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ #define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ #define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ #define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ #define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ #define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ #define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ #define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ #define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ #define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ #define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ #define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ #define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ #define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ #define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ #define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ #define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ #define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ #define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ #define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ #define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ #define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ #define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ #define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ #define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ #define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ #define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ #define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ #define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ #define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ #define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ #define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ /* SCB Configurable Fault Status Register Definitions */ #define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ #define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ #define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ #define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ #define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ #define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ /* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ #define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ #define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ #define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ #define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ #define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ #define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ #define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ #define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ #define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ #define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ #define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ /* BusFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ #define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ #define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ #define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ #define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ #define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ #define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ #define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ #define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ #define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ #define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ #define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ #define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ #define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ /* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ #define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ #define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ #define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ #define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ #define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ #define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ #define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ #define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ #define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ #define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ #define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ #define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ #define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ /* SCB Hard Fault Status Register Definitions */ #define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ #define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ #define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ #define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ #define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ #define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ /* SCB Debug Fault Status Register Definitions */ #define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ #define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ #define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ #define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ #define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ #define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ #define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ #define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ #define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ #define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ /* SCB Non-Secure Access Control Register Definitions */ #define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ #define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ #define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ #define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ #define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ #define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ /* SCB Cache Level ID Register Definitions */ #define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ #define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ #define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ #define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ /* SCB Cache Type Register Definitions */ #define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ #define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ #define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ #define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ #define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ #define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ #define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ #define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ #define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ #define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ /* SCB Cache Size ID Register Definitions */ #define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ #define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ #define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ #define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ #define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ #define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ #define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ #define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ #define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ #define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ #define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ #define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ #define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ #define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ /* SCB Cache Size Selection Register Definitions */ #define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ #define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ #define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ #define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ /* SCB Software Triggered Interrupt Register Definitions */ #define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ #define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ /* SCB D-Cache Invalidate by Set-way Register Definitions */ #define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ #define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ #define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ #define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ /* SCB D-Cache Clean by Set-way Register Definitions */ #define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ #define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ #define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ #define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ /* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ #define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ #define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ #define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ #define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ /*@} end of group CMSIS_SCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) \brief Type definitions for the System Control and ID Register not in the SCB @{ */ /** \brief Structure type to access the System Control and ID Register not in the SCB. */ typedef struct { uint32_t RESERVED0[1U]; __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ } SCnSCB_Type; /* Interrupt Controller Type Register Definitions */ #define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ #define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ /*@} end of group CMSIS_SCnotSCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SysTick System Tick Timer (SysTick) \brief Type definitions for the System Timer Registers. @{ */ /** \brief Structure type to access the System Timer (SysTick). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; /* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ /* SysTick Calibration Register Definitions */ #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ /*@} end of group CMSIS_SysTick */ /** \ingroup CMSIS_core_register \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) \brief Type definitions for the Instrumentation Trace Macrocell (ITM) @{ */ /** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). */ typedef struct { __OM union { __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ uint32_t RESERVED0[864U]; __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ uint32_t RESERVED1[15U]; __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ uint32_t RESERVED2[15U]; __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ uint32_t RESERVED3[32U]; uint32_t RESERVED4[43U]; __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ uint32_t RESERVED5[1U]; __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ uint32_t RESERVED6[4U]; __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ } ITM_Type; /* ITM Stimulus Port Register Definitions */ #define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ #define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ #define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ #define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ /* ITM Trace Privilege Register Definitions */ #define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ #define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ /* ITM Trace Control Register Definitions */ #define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ #define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ #define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ #define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ #define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ #define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ #define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ #define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ #define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ #define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ #define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ #define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ #define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ #define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ #define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ #define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ #define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ #define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ #define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ #define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ /* ITM Lock Status Register Definitions */ #define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ #define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ #define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ #define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ #define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ #define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ /*@}*/ /* end of group CMSIS_ITM */ /** \ingroup CMSIS_core_register \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) \brief Type definitions for the Data Watchpoint and Trace (DWT) @{ */ /** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ uint32_t RESERVED1[1U]; __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ uint32_t RESERVED2[1U]; __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ uint32_t RESERVED3[1U]; __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ uint32_t RESERVED4[1U]; __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ uint32_t RESERVED5[1U]; __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ uint32_t RESERVED6[1U]; __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ uint32_t RESERVED7[1U]; __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ uint32_t RESERVED8[1U]; __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ uint32_t RESERVED9[1U]; __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ uint32_t RESERVED10[1U]; __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ uint32_t RESERVED11[1U]; __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ uint32_t RESERVED12[1U]; __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ uint32_t RESERVED13[1U]; __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ uint32_t RESERVED14[1U]; __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ uint32_t RESERVED15[1U]; __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ uint32_t RESERVED16[1U]; __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ uint32_t RESERVED17[1U]; __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ uint32_t RESERVED18[1U]; __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ uint32_t RESERVED19[1U]; __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ uint32_t RESERVED20[1U]; __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ uint32_t RESERVED21[1U]; __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ uint32_t RESERVED22[1U]; __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ uint32_t RESERVED23[1U]; __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ uint32_t RESERVED24[1U]; __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ uint32_t RESERVED25[1U]; __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ uint32_t RESERVED26[1U]; __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ uint32_t RESERVED27[1U]; __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ uint32_t RESERVED28[1U]; __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ uint32_t RESERVED29[1U]; __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ uint32_t RESERVED30[1U]; __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ uint32_t RESERVED31[1U]; __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ uint32_t RESERVED32[934U]; __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ uint32_t RESERVED33[1U]; __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ } DWT_Type; /* DWT Control Register Definitions */ #define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ #define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ #define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ #define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ #define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ #define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ #define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ #define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ #define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ #define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ #define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ #define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ #define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ #define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ #define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ #define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ #define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ #define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ #define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ #define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ #define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ #define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ #define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ #define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ #define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ #define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ #define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ #define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ #define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ #define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ #define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ #define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ #define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ #define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ #define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ #define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ #define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ #define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ /* DWT CPI Count Register Definitions */ #define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ #define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ /* DWT Exception Overhead Count Register Definitions */ #define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ #define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ /* DWT Sleep Count Register Definitions */ #define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ #define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ /* DWT LSU Count Register Definitions */ #define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ #define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ /* DWT Folded-instruction Count Register Definitions */ #define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ #define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ /* DWT Comparator Function Register Definitions */ #define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ #define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ #define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ #define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ #define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ #define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ #define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ #define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ #define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ #define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ /*@}*/ /* end of group CMSIS_DWT */ /** \ingroup CMSIS_core_register \defgroup CMSIS_TPI Trace Port Interface (TPI) \brief Type definitions for the Trace Port Interface (TPI) @{ */ /** \brief Structure type to access the Trace Port Interface Register (TPI). */ typedef struct { __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ uint32_t RESERVED1[55U]; __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ uint32_t RESERVED2[131U]; __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ uint32_t RESERVED3[759U]; __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ uint32_t RESERVED4[1U]; __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ uint32_t RESERVED5[39U]; __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ uint32_t RESERVED7[8U]; __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ } TPI_Type; /* TPI Asynchronous Clock Prescaler Register Definitions */ #define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ #define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ /* TPI Selected Pin Protocol Register Definitions */ #define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ #define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ /* TPI Formatter and Flush Status Register Definitions */ #define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ #define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ #define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ #define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ #define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ #define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ #define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ #define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ /* TPI Formatter and Flush Control Register Definitions */ #define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ #define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ #define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ #define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ #define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ #define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ /* TPI TRIGGER Register Definitions */ #define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ #define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ /* TPI Integration Test FIFO Test Data 0 Register Definitions */ #define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ #define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ #define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ #define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ #define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ #define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ #define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ #define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ #define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ #define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ #define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ #define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ #define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ #define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ /* TPI Integration Test ATB Control Register 2 Register Definitions */ #define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ #define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ #define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ #define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ #define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ #define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ #define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ #define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ /* TPI Integration Test FIFO Test Data 1 Register Definitions */ #define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ #define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ #define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ #define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ #define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ #define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ #define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ #define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ #define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ #define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ #define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ #define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ #define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ #define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ /* TPI Integration Test ATB Control Register 0 Definitions */ #define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ #define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ #define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ #define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ #define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ #define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ #define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ #define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ /* TPI Integration Mode Control Register Definitions */ #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ #define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ #define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ #define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ #define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ #define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ #define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ #define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ #define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ #define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ #define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ #define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ #define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ #define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ /*@}*/ /* end of group CMSIS_TPI */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) /** \ingroup CMSIS_core_register \defgroup CMSIS_MPU Memory Protection Unit (MPU) \brief Type definitions for the Memory Protection Unit (MPU) @{ */ /** \brief Structure type to access the Memory Protection Unit (MPU). */ typedef struct { __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ uint32_t RESERVED0[1]; union { __IOM uint32_t MAIR[2]; struct { __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ }; }; } MPU_Type; #define MPU_TYPE_RALIASES 4U /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ #define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ #define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ #define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ #define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ /* MPU Control Register Definitions */ #define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ #define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ #define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ #define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ #define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ #define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ /* MPU Region Number Register Definitions */ #define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ #define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ /* MPU Region Base Address Register Definitions */ #define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ #define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ #define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ #define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ #define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ #define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ #define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ #define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ /* MPU Region Limit Address Register Definitions */ #define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ #define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ #define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ #define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ #define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ #define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ /* MPU Memory Attribute Indirection Register 0 Definitions */ #define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ #define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ #define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ #define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ #define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ #define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ #define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ #define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ /* MPU Memory Attribute Indirection Register 1 Definitions */ #define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ #define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ #define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ #define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ #define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ #define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ #define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ #define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ /*@} end of group CMSIS_MPU */ #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \ingroup CMSIS_core_register \defgroup CMSIS_SAU Security Attribution Unit (SAU) \brief Type definitions for the Security Attribution Unit (SAU) @{ */ /** \brief Structure type to access the Security Attribution Unit (SAU). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ #if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ #else uint32_t RESERVED0[3]; #endif __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ } SAU_Type; /* SAU Control Register Definitions */ #define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ #define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ #define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ #define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ /* SAU Type Register Definitions */ #define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ #define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ #if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) /* SAU Region Number Register Definitions */ #define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ #define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ /* SAU Region Base Address Register Definitions */ #define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ #define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ /* SAU Region Limit Address Register Definitions */ #define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ #define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ #define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ #define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ #define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ #define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ #endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ /* Secure Fault Status Register Definitions */ #define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ #define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ #define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ #define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ #define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ #define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ #define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ #define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ #define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ #define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ #define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ #define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ #define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ #define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ #define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ #define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ /*@} end of group CMSIS_SAU */ #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /** \ingroup CMSIS_core_register \defgroup CMSIS_FPU Floating Point Unit (FPU) \brief Type definitions for the Floating Point Unit (FPU) @{ */ /** \brief Structure type to access the Floating Point Unit (FPU). */ typedef struct { uint32_t RESERVED0[1U]; __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ } FPU_Type; /* Floating-Point Context Control Register Definitions */ #define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ #define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ #define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ #define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ #define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ #define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ #define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ #define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ #define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ #define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ #define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ #define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ #define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ #define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ #define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ #define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ #define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ #define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ #define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ #define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ #define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ #define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ #define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ #define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ #define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ #define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ #define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ #define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ #define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ #define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ #define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ #define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ #define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ #define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ /* Floating-Point Context Address Register Definitions */ #define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ #define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ /* Floating-Point Default Status Control Register Definitions */ #define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ #define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ #define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ #define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ #define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ #define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ #define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ #define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ /* Media and FP Feature Register 0 Definitions */ #define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ #define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ #define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ #define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ #define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ #define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ #define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ #define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ #define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ #define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ #define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ #define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ #define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ #define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ #define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ #define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ /* Media and FP Feature Register 1 Definitions */ #define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ #define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ #define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ #define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ #define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ #define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ #define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ #define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ /*@} end of group CMSIS_FPU */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) \brief Type definitions for the Core Debug Registers @{ */ /** \brief Structure type to access the Core Debug Register (CoreDebug). */ typedef struct { __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ uint32_t RESERVED4[1U]; __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ } CoreDebug_Type; /* Debug Halting Control and Status Register Definitions */ #define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ #define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ #define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ #define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ #define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ #define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ #define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ #define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ #define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ #define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ #define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ #define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ #define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ #define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ #define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ #define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ #define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ #define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ #define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ #define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ #define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ #define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ #define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ #define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ /* Debug Core Register Selector Register Definitions */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ #define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ /* Debug Exception and Monitor Control Register Definitions */ #define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ #define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ #define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ #define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ #define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ #define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ #define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ #define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ #define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ #define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ #define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ #define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ #define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ #define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ #define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ #define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ #define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ #define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ #define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ #define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ #define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ #define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ #define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ #define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ #define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ #define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ /* Debug Authentication Control Register Definitions */ #define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ #define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ #define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ #define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ #define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ #define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ #define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ #define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ /* Debug Security Control and Status Register Definitions */ #define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ #define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ #define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ #define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ #define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ #define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ /*@} end of group CMSIS_CoreDebug */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_bitfield Core register bit field macros \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). @{ */ /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_base Core Definitions \brief Definitions for base addresses, unions, and structures. @{ */ /* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ #endif #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ #endif #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /*@} */ /******************************************************************************* * Hardware Abstraction Layer Core Function Interface contains: - Core NVIC Functions - Core SysTick Functions - Core Debug Functions - Core Register Access Functions ******************************************************************************/ /** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference */ /* ########################## NVIC functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_NVICFunctions NVIC Functions \brief Functions that manage interrupts and exceptions via the NVIC. @{ */ #ifdef CMSIS_NVIC_VIRTUAL #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" #endif #include CMSIS_NVIC_VIRTUAL_HEADER_FILE #else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ #define NVIC_GetActive __NVIC_GetActive #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ #ifdef CMSIS_VECTAB_VIRTUAL #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" #endif #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE #else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ #define NVIC_USER_IRQ_OFFSET 16 /* Special LR values for Secure/Non-Secure call handling and exception handling */ /* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ #define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ /* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ #define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ #define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ #define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ #define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ #define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ #define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ #define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ /* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ #define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ #else #define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ #endif /** \brief Set Priority Grouping \details Sets the priority grouping field using the required unlock sequence. The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Priority grouping field. */ __STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ reg_value = SCB->AIRCR; /* read old register configuration */ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB->AIRCR = reg_value; } /** \brief Get Priority Grouping \details Reads the priority grouping field from the NVIC Interrupt Controller. \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ __STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) { return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); } /** \brief Enable Interrupt \details Enables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { __COMPILER_BARRIER(); NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __COMPILER_BARRIER(); } } /** \brief Get Interrupt Enable status \details Returns a device specific interrupt enable status from the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt \details Disables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } } /** \brief Get Pending Interrupt \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt \details Sets the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt \details Clears the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Get Interrupt Target State \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure \return 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Target State \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Clear Interrupt Target State \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /** \brief Set Interrupt Priority \details Sets the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every processor exception. */ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } /** \brief Get Interrupt Priority \details Reads the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } /** \brief Encode Priority \details Encodes the priority for an interrupt with the given priority group, preemptive priority value, and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Used priority group. \param [in] PreemptPriority Preemptive priority value (starting from 0). \param [in] SubPriority Subpriority value (starting from 0). \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). */ __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); return ( ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) ); } /** \brief Decode Priority \details Decodes an interrupt priority value with a given priority group to preemptive priority value and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). \param [in] PriorityGroup Used priority group. \param [out] pPreemptPriority Preemptive priority value (starting from 0). \param [out] pSubPriority Subpriority value (starting from 0). */ __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); } /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. VTOR must been relocated to SRAM before. \param [in] IRQn Interrupt number \param [in] vector Address of interrupt handler function */ __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { uint32_t *vectors = (uint32_t *)SCB->VTOR; vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; __DSB(); } /** \brief Get Interrupt Vector \details Reads an interrupt vector from interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Address of interrupt handler function */ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) { uint32_t *vectors = (uint32_t *)SCB->VTOR; return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; } /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ __DSB(); /* Ensure completion of memory access */ for(;;) /* wait until reset */ { __NOP(); } } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Set Priority Grouping (non-secure) \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Priority grouping field. */ __STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ reg_value = SCB_NS->AIRCR; /* read old register configuration */ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB_NS->AIRCR = reg_value; } /** \brief Get Priority Grouping (non-secure) \details Reads the priority grouping field from the non-secure NVIC when in secure state. \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ __STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) { return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); } /** \brief Enable Interrupt (non-secure) \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Interrupt Enable status (non-secure) \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt (non-secure) \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Pending Interrupt (non-secure) \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt (non-secure) \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt (non-secure) \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt (non-secure) \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Priority (non-secure) \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every non-secure processor exception. */ __STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } /** \brief Get Interrupt Priority (non-secure) \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } #endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ /*@} end of CMSIS_Core_NVICFunctions */ /* ########################## MPU functions #################################### */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #include "mpu_armv8.h" #endif /* ########################## FPU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_FpuFunctions FPU Functions \brief Function that provides FPU type. @{ */ /** \brief get FPU type \details returns the FPU type \returns - \b 0: No FPU - \b 1: Single precision FPU - \b 2: Double + Single precision FPU */ __STATIC_INLINE uint32_t SCB_GetFPUType(void) { uint32_t mvfr0; mvfr0 = FPU->MVFR0; if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) { return 2U; /* Double + Single precision FPU */ } else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) { return 1U; /* Single precision FPU */ } else { return 0U; /* No FPU */ } } /*@} end of CMSIS_Core_FpuFunctions */ /* ########################## SAU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SAUFunctions SAU Functions \brief Functions that configure the SAU. @{ */ #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Enable SAU \details Enables the Security Attribution Unit (SAU). */ __STATIC_INLINE void TZ_SAU_Enable(void) { SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); } /** \brief Disable SAU \details Disables the Security Attribution Unit (SAU). */ __STATIC_INLINE void TZ_SAU_Disable(void) { SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /*@} end of CMSIS_Core_SAUFunctions */ /* ################################## SysTick function ############################################ */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SysTickFunctions SysTick Functions \brief Functions that configure the System. @{ */ #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief System Tick Configuration (non-secure) \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function TZ_SysTick_Config_NS is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ #endif /*@} end of CMSIS_Core_SysTickFunctions */ /* ##################################### Debug In/Output function ########################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_core_DebugFunctions ITM Functions \brief Functions that access the ITM debug interface. @{ */ extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ #define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ /** \brief ITM Send Character \details Transmits a character via the ITM channel 0, and \li Just returns when no debugger is connected that has booked the output. \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. \param [in] ch Character to transmit. \returns Character to transmit. */ __STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) { if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ { while (ITM->PORT[0U].u32 == 0UL) { __NOP(); } ITM->PORT[0U].u8 = (uint8_t)ch; } return (ch); } /** \brief ITM Receive Character \details Inputs a character via the external variable \ref ITM_RxBuffer. \return Received character. \return -1 No character pending. */ __STATIC_INLINE int32_t ITM_ReceiveChar (void) { int32_t ch = -1; /* no character available */ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { ch = ITM_RxBuffer; ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ } return (ch); } /** \brief ITM Check Character \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. \return 0 No character available. \return 1 Character available. */ __STATIC_INLINE int32_t ITM_CheckChar (void) { if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { return (0); /* no character available */ } else { return (1); /* character available */ } } /*@} end of CMSIS_core_DebugFunctions */ #ifdef __cplusplus } #endif #endif /* __CORE_CM33_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ ================================================ FILE: 3rd_party/CMSIS/Include/core_cm35p.h ================================================ /**************************************************************************//** * @file core_cm35p.h * @brief CMSIS Cortex-M35P Core Peripheral Access Layer Header File * @version V1.0.0 * @date 12. November 2018 ******************************************************************************/ /* * Copyright (c) 2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_CM35P_H_GENERIC #define __CORE_CM35P_H_GENERIC #include #ifdef __cplusplus extern "C" { #endif /** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions CMSIS violates the following MISRA-C:2004 rules: \li Required Rule 8.5, object/function definition in header file.
Function definitions in header files are used to allow 'inlining'. \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
Unions are used for effective representation of core registers. \li Advisory Rule 19.7, Function-like macro defined.
Function-like macros are used to allow more efficient code. */ /******************************************************************************* * CMSIS definitions ******************************************************************************/ /** \ingroup Cortex_M35P @{ */ #include "cmsis_version.h" /* CMSIS CM35P definitions */ #define __CM35P_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ #define __CM35P_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM35P_CMSIS_VERSION ((__CM35P_CMSIS_VERSION_MAIN << 16U) | \ __CM35P_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (35U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. */ #if defined ( __CC_ARM ) #if defined (__TARGET_FPU_VFP) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined (__ARM_FP) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined ( __ICCARM__ ) #if defined (__ARMVFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined ( __TI_ARM__ ) #if defined (__TI_VFP_SUPPORT__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __TASKING__ ) #if defined (__FPU_VFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __CSMC__ ) #if ( __CSMC__ & 0x400U) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #endif #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ #ifdef __cplusplus } #endif #endif /* __CORE_CM35P_H_GENERIC */ #ifndef __CMSIS_GENERIC #ifndef __CORE_CM35P_H_DEPENDANT #define __CORE_CM35P_H_DEPENDANT #ifdef __cplusplus extern "C" { #endif /* check device defines and use defaults */ #if defined __CHECK_DEVICE_DEFINES #ifndef __CM35P_REV #define __CM35P_REV 0x0000U #warning "__CM35P_REV not defined in device header file; using default!" #endif #ifndef __FPU_PRESENT #define __FPU_PRESENT 0U #warning "__FPU_PRESENT not defined in device header file; using default!" #endif #ifndef __MPU_PRESENT #define __MPU_PRESENT 0U #warning "__MPU_PRESENT not defined in device header file; using default!" #endif #ifndef __SAUREGION_PRESENT #define __SAUREGION_PRESENT 0U #warning "__SAUREGION_PRESENT not defined in device header file; using default!" #endif #ifndef __DSP_PRESENT #define __DSP_PRESENT 0U #warning "__DSP_PRESENT not defined in device header file; using default!" #endif #ifndef __NVIC_PRIO_BITS #define __NVIC_PRIO_BITS 3U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif #ifndef __Vendor_SysTickConfig #define __Vendor_SysTickConfig 0U #warning "__Vendor_SysTickConfig not defined in device header file; using default!" #endif #endif /* IO definitions (access restrictions to peripheral registers) */ /** \defgroup CMSIS_glob_defs CMSIS Global Defines IO Type Qualifiers are used \li to specify the access to peripheral variables. \li for automatic generation of peripheral register debug information. */ #ifdef __cplusplus #define __I volatile /*!< Defines 'read only' permissions */ #else #define __I volatile const /*!< Defines 'read only' permissions */ #endif #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */ /* following defines should be used for structure members */ #define __IM volatile const /*! Defines 'read only' structure member permissions */ #define __OM volatile /*! Defines 'write only' structure member permissions */ #define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group Cortex_M35P */ /******************************************************************************* * Register Abstraction Core Register contain: - Core Register - Core NVIC Register - Core SCB Register - Core SysTick Register - Core Debug Register - Core MPU Register - Core SAU Register - Core FPU Register ******************************************************************************/ /** \defgroup CMSIS_core_register Defines and Type Definitions \brief Type definitions and defines for Cortex-M processor based devices. */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CORE Status and Control Registers \brief Core Register type definitions. @{ */ /** \brief Union type to access the Application Program Status Register (APSR). */ typedef union { struct { uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } APSR_Type; /* APSR Register Definitions */ #define APSR_N_Pos 31U /*!< APSR: N Position */ #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ #define APSR_Z_Pos 30U /*!< APSR: Z Position */ #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ #define APSR_C_Pos 29U /*!< APSR: C Position */ #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ #define APSR_V_Pos 28U /*!< APSR: V Position */ #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ #define APSR_Q_Pos 27U /*!< APSR: Q Position */ #define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ #define APSR_GE_Pos 16U /*!< APSR: GE Position */ #define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ /** \brief Union type to access the Interrupt Program Status Register (IPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } IPSR_Type; /* IPSR Register Definitions */ #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ /** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } xPSR_Type; /* xPSR Register Definitions */ #define xPSR_N_Pos 31U /*!< xPSR: N Position */ #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ #define xPSR_C_Pos 29U /*!< xPSR: C Position */ #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ #define xPSR_V_Pos 28U /*!< xPSR: V Position */ #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ #define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ #define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ #define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ #define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ #define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ #define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ /** \brief Union type to access the Control Registers (CONTROL). */ typedef union { struct { uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } CONTROL_Type; /* CONTROL Register Definitions */ #define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ #define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ #define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ #define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ #define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ #define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ /*@} end of group CMSIS_CORE */ /** \ingroup CMSIS_core_register \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) \brief Type definitions for the NVIC Registers @{ */ /** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). */ typedef struct { __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[16U]; __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ uint32_t RSERVED1[16U]; __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[16U]; __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ uint32_t RESERVED3[16U]; __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ uint32_t RESERVED4[16U]; __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ uint32_t RESERVED5[16U]; __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ uint32_t RESERVED6[580U]; __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ } NVIC_Type; /* Software Triggered Interrupt Register Definitions */ #define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ #define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ /*@} end of group CMSIS_NVIC */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCB System Control Block (SCB) \brief Type definitions for the System Control Block Registers @{ */ /** \brief Structure type to access the System Control Block (SCB). */ typedef struct { __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ uint32_t RESERVED3[92U]; __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ uint32_t RESERVED4[15U]; __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ uint32_t RESERVED5[1U]; __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ uint32_t RESERVED6[1U]; __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ } SCB_Type; /* SCB CPUID Register Definitions */ #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ /* SCB Interrupt Control State Register Definitions */ #define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ #define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ #define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ #define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ #define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ #define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ #define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ #define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ #define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ #define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ /* SCB Vector Table Offset Register Definitions */ #define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ #define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ /* SCB Application Interrupt and Reset Control Register Definitions */ #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ #define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ #define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ #define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ #define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ #define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ #define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ #define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ #define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ /* SCB System Control Register Definitions */ #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ #define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ #define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ /* SCB Configuration Control Register Definitions */ #define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ #define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ #define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ #define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ #define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ #define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ #define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ #define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ #define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ #define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ #define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ #define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ #define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ #define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ /* SCB System Handler Control and State Register Definitions */ #define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ #define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ #define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ #define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ #define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ #define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ #define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ #define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ #define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ #define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ #define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ #define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ #define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ #define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ #define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ #define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ #define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ #define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ #define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ #define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ #define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ #define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ #define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ #define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ #define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ #define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ #define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ #define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ #define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ #define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ #define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ #define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ #define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ #define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ #define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ #define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ #define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ #define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ /* SCB Configurable Fault Status Register Definitions */ #define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ #define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ #define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ #define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ #define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ #define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ /* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ #define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ #define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ #define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ #define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ #define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ #define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ #define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ #define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ #define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ #define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ #define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ /* BusFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ #define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ #define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ #define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ #define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ #define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ #define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ #define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ #define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ #define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ #define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ #define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ #define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ #define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ /* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ #define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ #define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ #define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ #define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ #define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ #define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ #define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ #define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ #define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ #define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ #define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ #define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ #define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ /* SCB Hard Fault Status Register Definitions */ #define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ #define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ #define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ #define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ #define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ #define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ /* SCB Debug Fault Status Register Definitions */ #define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ #define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ #define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ #define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ #define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ #define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ #define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ #define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ #define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ #define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ /* SCB Non-Secure Access Control Register Definitions */ #define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ #define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ #define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ #define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ #define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ #define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ /* SCB Cache Level ID Register Definitions */ #define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ #define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ #define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ #define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ /* SCB Cache Type Register Definitions */ #define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ #define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ #define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ #define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ #define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ #define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ #define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ #define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ #define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ #define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ /* SCB Cache Size ID Register Definitions */ #define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ #define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ #define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ #define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ #define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ #define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ #define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ #define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ #define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ #define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ #define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ #define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ #define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ #define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ /* SCB Cache Size Selection Register Definitions */ #define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ #define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ #define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ #define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ /* SCB Software Triggered Interrupt Register Definitions */ #define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ #define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ /* SCB D-Cache Invalidate by Set-way Register Definitions */ #define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ #define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ #define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ #define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ /* SCB D-Cache Clean by Set-way Register Definitions */ #define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ #define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ #define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ #define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ /* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ #define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ #define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ #define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ #define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ /*@} end of group CMSIS_SCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) \brief Type definitions for the System Control and ID Register not in the SCB @{ */ /** \brief Structure type to access the System Control and ID Register not in the SCB. */ typedef struct { uint32_t RESERVED0[1U]; __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ } SCnSCB_Type; /* Interrupt Controller Type Register Definitions */ #define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ #define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ /*@} end of group CMSIS_SCnotSCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SysTick System Tick Timer (SysTick) \brief Type definitions for the System Timer Registers. @{ */ /** \brief Structure type to access the System Timer (SysTick). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; /* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ /* SysTick Calibration Register Definitions */ #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ /*@} end of group CMSIS_SysTick */ /** \ingroup CMSIS_core_register \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) \brief Type definitions for the Instrumentation Trace Macrocell (ITM) @{ */ /** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). */ typedef struct { __OM union { __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ uint32_t RESERVED0[864U]; __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ uint32_t RESERVED1[15U]; __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ uint32_t RESERVED2[15U]; __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ uint32_t RESERVED3[32U]; uint32_t RESERVED4[43U]; __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ uint32_t RESERVED5[1U]; __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ uint32_t RESERVED6[4U]; __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ } ITM_Type; /* ITM Stimulus Port Register Definitions */ #define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ #define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ #define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ #define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ /* ITM Trace Privilege Register Definitions */ #define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ #define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ /* ITM Trace Control Register Definitions */ #define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ #define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ #define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ #define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ #define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ #define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ #define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ #define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ #define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ #define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ #define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ #define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ #define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ #define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ #define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ #define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ #define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ #define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ #define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ #define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ /* ITM Lock Status Register Definitions */ #define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ #define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ #define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ #define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ #define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ #define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ /*@}*/ /* end of group CMSIS_ITM */ /** \ingroup CMSIS_core_register \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) \brief Type definitions for the Data Watchpoint and Trace (DWT) @{ */ /** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ uint32_t RESERVED1[1U]; __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ uint32_t RESERVED2[1U]; __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ uint32_t RESERVED3[1U]; __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ uint32_t RESERVED4[1U]; __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ uint32_t RESERVED5[1U]; __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ uint32_t RESERVED6[1U]; __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ uint32_t RESERVED7[1U]; __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ uint32_t RESERVED8[1U]; __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ uint32_t RESERVED9[1U]; __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ uint32_t RESERVED10[1U]; __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ uint32_t RESERVED11[1U]; __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ uint32_t RESERVED12[1U]; __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ uint32_t RESERVED13[1U]; __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ uint32_t RESERVED14[1U]; __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ uint32_t RESERVED15[1U]; __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ uint32_t RESERVED16[1U]; __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ uint32_t RESERVED17[1U]; __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ uint32_t RESERVED18[1U]; __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ uint32_t RESERVED19[1U]; __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ uint32_t RESERVED20[1U]; __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ uint32_t RESERVED21[1U]; __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ uint32_t RESERVED22[1U]; __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ uint32_t RESERVED23[1U]; __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ uint32_t RESERVED24[1U]; __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ uint32_t RESERVED25[1U]; __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ uint32_t RESERVED26[1U]; __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ uint32_t RESERVED27[1U]; __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ uint32_t RESERVED28[1U]; __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ uint32_t RESERVED29[1U]; __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ uint32_t RESERVED30[1U]; __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ uint32_t RESERVED31[1U]; __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ uint32_t RESERVED32[934U]; __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ uint32_t RESERVED33[1U]; __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ } DWT_Type; /* DWT Control Register Definitions */ #define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ #define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ #define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ #define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ #define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ #define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ #define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ #define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ #define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ #define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ #define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ #define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ #define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ #define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ #define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ #define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ #define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ #define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ #define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ #define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ #define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ #define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ #define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ #define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ #define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ #define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ #define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ #define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ #define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ #define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ #define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ #define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ #define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ #define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ #define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ #define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ #define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ #define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ /* DWT CPI Count Register Definitions */ #define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ #define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ /* DWT Exception Overhead Count Register Definitions */ #define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ #define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ /* DWT Sleep Count Register Definitions */ #define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ #define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ /* DWT LSU Count Register Definitions */ #define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ #define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ /* DWT Folded-instruction Count Register Definitions */ #define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ #define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ /* DWT Comparator Function Register Definitions */ #define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ #define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ #define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ #define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ #define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ #define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ #define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ #define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ #define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ #define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ /*@}*/ /* end of group CMSIS_DWT */ /** \ingroup CMSIS_core_register \defgroup CMSIS_TPI Trace Port Interface (TPI) \brief Type definitions for the Trace Port Interface (TPI) @{ */ /** \brief Structure type to access the Trace Port Interface Register (TPI). */ typedef struct { __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ uint32_t RESERVED1[55U]; __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ uint32_t RESERVED2[131U]; __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ uint32_t RESERVED3[759U]; __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ uint32_t RESERVED4[1U]; __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ uint32_t RESERVED5[39U]; __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ uint32_t RESERVED7[8U]; __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ } TPI_Type; /* TPI Asynchronous Clock Prescaler Register Definitions */ #define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ #define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ /* TPI Selected Pin Protocol Register Definitions */ #define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ #define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ /* TPI Formatter and Flush Status Register Definitions */ #define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ #define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ #define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ #define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ #define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ #define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ #define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ #define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ /* TPI Formatter and Flush Control Register Definitions */ #define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ #define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ #define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ #define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ #define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ #define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ /* TPI TRIGGER Register Definitions */ #define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ #define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ /* TPI Integration Test FIFO Test Data 0 Register Definitions */ #define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ #define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ #define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ #define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ #define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ #define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ #define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ #define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ #define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ #define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ #define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ #define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ #define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ #define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ /* TPI Integration Test ATB Control Register 2 Register Definitions */ #define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ #define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ #define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ #define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ #define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ #define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ #define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ #define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ /* TPI Integration Test FIFO Test Data 1 Register Definitions */ #define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ #define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ #define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ #define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ #define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ #define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ #define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ #define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ #define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ #define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ #define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ #define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ #define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ #define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ /* TPI Integration Test ATB Control Register 0 Definitions */ #define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ #define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ #define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ #define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ #define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ #define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ #define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ #define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ /* TPI Integration Mode Control Register Definitions */ #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ #define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ #define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ #define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ #define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ #define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ #define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ #define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ #define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ #define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ #define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ #define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ #define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ #define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ /*@}*/ /* end of group CMSIS_TPI */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) /** \ingroup CMSIS_core_register \defgroup CMSIS_MPU Memory Protection Unit (MPU) \brief Type definitions for the Memory Protection Unit (MPU) @{ */ /** \brief Structure type to access the Memory Protection Unit (MPU). */ typedef struct { __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ uint32_t RESERVED0[1]; union { __IOM uint32_t MAIR[2]; struct { __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ }; }; } MPU_Type; #define MPU_TYPE_RALIASES 4U /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ #define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ #define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ #define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ #define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ /* MPU Control Register Definitions */ #define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ #define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ #define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ #define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ #define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ #define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ /* MPU Region Number Register Definitions */ #define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ #define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ /* MPU Region Base Address Register Definitions */ #define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ #define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ #define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ #define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ #define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ #define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ #define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ #define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ /* MPU Region Limit Address Register Definitions */ #define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ #define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ #define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ #define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ #define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ #define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ /* MPU Memory Attribute Indirection Register 0 Definitions */ #define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ #define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ #define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ #define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ #define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ #define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ #define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ #define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ /* MPU Memory Attribute Indirection Register 1 Definitions */ #define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ #define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ #define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ #define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ #define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ #define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ #define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ #define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ /*@} end of group CMSIS_MPU */ #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \ingroup CMSIS_core_register \defgroup CMSIS_SAU Security Attribution Unit (SAU) \brief Type definitions for the Security Attribution Unit (SAU) @{ */ /** \brief Structure type to access the Security Attribution Unit (SAU). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ #if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ #else uint32_t RESERVED0[3]; #endif __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ } SAU_Type; /* SAU Control Register Definitions */ #define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ #define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ #define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ #define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ /* SAU Type Register Definitions */ #define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ #define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ #if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) /* SAU Region Number Register Definitions */ #define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ #define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ /* SAU Region Base Address Register Definitions */ #define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ #define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ /* SAU Region Limit Address Register Definitions */ #define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ #define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ #define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ #define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ #define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ #define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ #endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ /* Secure Fault Status Register Definitions */ #define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ #define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ #define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ #define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ #define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ #define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ #define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ #define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ #define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ #define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ #define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ #define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ #define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ #define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ #define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ #define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ /*@} end of group CMSIS_SAU */ #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /** \ingroup CMSIS_core_register \defgroup CMSIS_FPU Floating Point Unit (FPU) \brief Type definitions for the Floating Point Unit (FPU) @{ */ /** \brief Structure type to access the Floating Point Unit (FPU). */ typedef struct { uint32_t RESERVED0[1U]; __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ } FPU_Type; /* Floating-Point Context Control Register Definitions */ #define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ #define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ #define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ #define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ #define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ #define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ #define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ #define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ #define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ #define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ #define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ #define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ #define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ #define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ #define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ #define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ #define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ #define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ #define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ #define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ #define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ #define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ #define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ #define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ #define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ #define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ #define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ #define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ #define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ #define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ #define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ #define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ #define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ #define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ /* Floating-Point Context Address Register Definitions */ #define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ #define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ /* Floating-Point Default Status Control Register Definitions */ #define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ #define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ #define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ #define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ #define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ #define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ #define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ #define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ /* Media and FP Feature Register 0 Definitions */ #define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ #define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ #define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ #define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ #define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ #define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ #define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ #define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ #define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ #define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ #define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ #define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ #define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ #define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ #define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ #define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ /* Media and FP Feature Register 1 Definitions */ #define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ #define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ #define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ #define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ #define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ #define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ #define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ #define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ /*@} end of group CMSIS_FPU */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) \brief Type definitions for the Core Debug Registers @{ */ /** \brief Structure type to access the Core Debug Register (CoreDebug). */ typedef struct { __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ uint32_t RESERVED4[1U]; __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ } CoreDebug_Type; /* Debug Halting Control and Status Register Definitions */ #define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ #define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ #define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ #define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ #define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ #define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ #define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ #define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ #define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ #define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ #define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ #define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ #define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ #define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ #define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ #define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ #define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ #define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ #define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ #define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ #define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ #define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ #define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ #define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ /* Debug Core Register Selector Register Definitions */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ #define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ /* Debug Exception and Monitor Control Register Definitions */ #define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ #define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ #define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ #define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ #define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ #define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ #define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ #define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ #define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ #define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ #define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ #define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ #define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ #define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ #define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ #define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ #define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ #define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ #define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ #define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ #define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ #define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ #define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ #define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ #define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ #define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ /* Debug Authentication Control Register Definitions */ #define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ #define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ #define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ #define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ #define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ #define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ #define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ #define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ /* Debug Security Control and Status Register Definitions */ #define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ #define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ #define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ #define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ #define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ #define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ /*@} end of group CMSIS_CoreDebug */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_bitfield Core register bit field macros \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). @{ */ /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_base Core Definitions \brief Definitions for base addresses, unions, and structures. @{ */ /* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ #endif #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ #endif #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /*@} */ /******************************************************************************* * Hardware Abstraction Layer Core Function Interface contains: - Core NVIC Functions - Core SysTick Functions - Core Debug Functions - Core Register Access Functions ******************************************************************************/ /** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference */ /* ########################## NVIC functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_NVICFunctions NVIC Functions \brief Functions that manage interrupts and exceptions via the NVIC. @{ */ #ifdef CMSIS_NVIC_VIRTUAL #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" #endif #include CMSIS_NVIC_VIRTUAL_HEADER_FILE #else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ #define NVIC_GetActive __NVIC_GetActive #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ #ifdef CMSIS_VECTAB_VIRTUAL #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" #endif #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE #else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ #define NVIC_USER_IRQ_OFFSET 16 /* Special LR values for Secure/Non-Secure call handling and exception handling */ /* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ #define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ /* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ #define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ #define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ #define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ #define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ #define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ #define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ #define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ /* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ #define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ #else #define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ #endif /** \brief Set Priority Grouping \details Sets the priority grouping field using the required unlock sequence. The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Priority grouping field. */ __STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ reg_value = SCB->AIRCR; /* read old register configuration */ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB->AIRCR = reg_value; } /** \brief Get Priority Grouping \details Reads the priority grouping field from the NVIC Interrupt Controller. \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ __STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) { return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); } /** \brief Enable Interrupt \details Enables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { __COMPILER_BARRIER(); NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __COMPILER_BARRIER(); } } /** \brief Get Interrupt Enable status \details Returns a device specific interrupt enable status from the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt \details Disables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } } /** \brief Get Pending Interrupt \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt \details Sets the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt \details Clears the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Get Interrupt Target State \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure \return 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Target State \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Clear Interrupt Target State \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /** \brief Set Interrupt Priority \details Sets the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every processor exception. */ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } /** \brief Get Interrupt Priority \details Reads the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } /** \brief Encode Priority \details Encodes the priority for an interrupt with the given priority group, preemptive priority value, and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Used priority group. \param [in] PreemptPriority Preemptive priority value (starting from 0). \param [in] SubPriority Subpriority value (starting from 0). \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). */ __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); return ( ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) ); } /** \brief Decode Priority \details Decodes an interrupt priority value with a given priority group to preemptive priority value and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). \param [in] PriorityGroup Used priority group. \param [out] pPreemptPriority Preemptive priority value (starting from 0). \param [out] pSubPriority Subpriority value (starting from 0). */ __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); } /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. VTOR must been relocated to SRAM before. \param [in] IRQn Interrupt number \param [in] vector Address of interrupt handler function */ __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { uint32_t *vectors = (uint32_t *)SCB->VTOR; vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; __DSB(); } /** \brief Get Interrupt Vector \details Reads an interrupt vector from interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Address of interrupt handler function */ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) { uint32_t *vectors = (uint32_t *)SCB->VTOR; return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; } /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ __DSB(); /* Ensure completion of memory access */ for(;;) /* wait until reset */ { __NOP(); } } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Set Priority Grouping (non-secure) \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Priority grouping field. */ __STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ reg_value = SCB_NS->AIRCR; /* read old register configuration */ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB_NS->AIRCR = reg_value; } /** \brief Get Priority Grouping (non-secure) \details Reads the priority grouping field from the non-secure NVIC when in secure state. \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ __STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) { return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); } /** \brief Enable Interrupt (non-secure) \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Interrupt Enable status (non-secure) \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt (non-secure) \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Pending Interrupt (non-secure) \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt (non-secure) \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt (non-secure) \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt (non-secure) \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Priority (non-secure) \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every non-secure processor exception. */ __STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } /** \brief Get Interrupt Priority (non-secure) \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } #endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ /*@} end of CMSIS_Core_NVICFunctions */ /* ########################## MPU functions #################################### */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #include "mpu_armv8.h" #endif /* ########################## FPU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_FpuFunctions FPU Functions \brief Function that provides FPU type. @{ */ /** \brief get FPU type \details returns the FPU type \returns - \b 0: No FPU - \b 1: Single precision FPU - \b 2: Double + Single precision FPU */ __STATIC_INLINE uint32_t SCB_GetFPUType(void) { uint32_t mvfr0; mvfr0 = FPU->MVFR0; if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) { return 2U; /* Double + Single precision FPU */ } else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) { return 1U; /* Single precision FPU */ } else { return 0U; /* No FPU */ } } /*@} end of CMSIS_Core_FpuFunctions */ /* ########################## SAU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SAUFunctions SAU Functions \brief Functions that configure the SAU. @{ */ #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Enable SAU \details Enables the Security Attribution Unit (SAU). */ __STATIC_INLINE void TZ_SAU_Enable(void) { SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); } /** \brief Disable SAU \details Disables the Security Attribution Unit (SAU). */ __STATIC_INLINE void TZ_SAU_Disable(void) { SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /*@} end of CMSIS_Core_SAUFunctions */ /* ################################## SysTick function ############################################ */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SysTickFunctions SysTick Functions \brief Functions that configure the System. @{ */ #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief System Tick Configuration (non-secure) \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function TZ_SysTick_Config_NS is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ #endif /*@} end of CMSIS_Core_SysTickFunctions */ /* ##################################### Debug In/Output function ########################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_core_DebugFunctions ITM Functions \brief Functions that access the ITM debug interface. @{ */ extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ #define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ /** \brief ITM Send Character \details Transmits a character via the ITM channel 0, and \li Just returns when no debugger is connected that has booked the output. \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. \param [in] ch Character to transmit. \returns Character to transmit. */ __STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) { if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ { while (ITM->PORT[0U].u32 == 0UL) { __NOP(); } ITM->PORT[0U].u8 = (uint8_t)ch; } return (ch); } /** \brief ITM Receive Character \details Inputs a character via the external variable \ref ITM_RxBuffer. \return Received character. \return -1 No character pending. */ __STATIC_INLINE int32_t ITM_ReceiveChar (void) { int32_t ch = -1; /* no character available */ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { ch = ITM_RxBuffer; ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ } return (ch); } /** \brief ITM Check Character \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. \return 0 No character available. \return 1 Character available. */ __STATIC_INLINE int32_t ITM_CheckChar (void) { if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { return (0); /* no character available */ } else { return (1); /* character available */ } } /*@} end of CMSIS_core_DebugFunctions */ #ifdef __cplusplus } #endif #endif /* __CORE_CM35P_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ ================================================ FILE: 3rd_party/CMSIS/Include/core_cm4.h ================================================ /**************************************************************************//** * @file core_cm4.h * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File * @version V5.1.0 * @date 13. March 2019 ******************************************************************************/ /* * Copyright (c) 2009-2019 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_CM4_H_GENERIC #define __CORE_CM4_H_GENERIC #include #ifdef __cplusplus extern "C" { #endif /** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions CMSIS violates the following MISRA-C:2004 rules: \li Required Rule 8.5, object/function definition in header file.
Function definitions in header files are used to allow 'inlining'. \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
Unions are used for effective representation of core registers. \li Advisory Rule 19.7, Function-like macro defined.
Function-like macros are used to allow more efficient code. */ /******************************************************************************* * CMSIS definitions ******************************************************************************/ /** \ingroup Cortex_M4 @{ */ #include "cmsis_version.h" /* CMSIS CM4 definitions */ #define __CM4_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ #define __CM4_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ __CM4_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (4U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. */ #if defined ( __CC_ARM ) #if defined __TARGET_FPU_VFP #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined __ARM_FP #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __TASKING__ ) #if defined __FPU_VFP__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __CSMC__ ) #if ( __CSMC__ & 0x400U) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #endif #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ #ifdef __cplusplus } #endif #endif /* __CORE_CM4_H_GENERIC */ #ifndef __CMSIS_GENERIC #ifndef __CORE_CM4_H_DEPENDANT #define __CORE_CM4_H_DEPENDANT #ifdef __cplusplus extern "C" { #endif /* check device defines and use defaults */ #if defined __CHECK_DEVICE_DEFINES #ifndef __CM4_REV #define __CM4_REV 0x0000U #warning "__CM4_REV not defined in device header file; using default!" #endif #ifndef __FPU_PRESENT #define __FPU_PRESENT 0U #warning "__FPU_PRESENT not defined in device header file; using default!" #endif #ifndef __MPU_PRESENT #define __MPU_PRESENT 0U #warning "__MPU_PRESENT not defined in device header file; using default!" #endif #ifndef __NVIC_PRIO_BITS #define __NVIC_PRIO_BITS 3U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif #ifndef __Vendor_SysTickConfig #define __Vendor_SysTickConfig 0U #warning "__Vendor_SysTickConfig not defined in device header file; using default!" #endif #endif /* IO definitions (access restrictions to peripheral registers) */ /** \defgroup CMSIS_glob_defs CMSIS Global Defines IO Type Qualifiers are used \li to specify the access to peripheral variables. \li for automatic generation of peripheral register debug information. */ #ifdef __cplusplus #define __I volatile /*!< Defines 'read only' permissions */ #else #define __I volatile const /*!< Defines 'read only' permissions */ #endif #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */ /* following defines should be used for structure members */ #define __IM volatile const /*! Defines 'read only' structure member permissions */ #define __OM volatile /*! Defines 'write only' structure member permissions */ #define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group Cortex_M4 */ /******************************************************************************* * Register Abstraction Core Register contain: - Core Register - Core NVIC Register - Core SCB Register - Core SysTick Register - Core Debug Register - Core MPU Register - Core FPU Register ******************************************************************************/ /** \defgroup CMSIS_core_register Defines and Type Definitions \brief Type definitions and defines for Cortex-M processor based devices. */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CORE Status and Control Registers \brief Core Register type definitions. @{ */ /** \brief Union type to access the Application Program Status Register (APSR). */ typedef union { struct { uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } APSR_Type; /* APSR Register Definitions */ #define APSR_N_Pos 31U /*!< APSR: N Position */ #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ #define APSR_Z_Pos 30U /*!< APSR: Z Position */ #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ #define APSR_C_Pos 29U /*!< APSR: C Position */ #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ #define APSR_V_Pos 28U /*!< APSR: V Position */ #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ #define APSR_Q_Pos 27U /*!< APSR: Q Position */ #define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ #define APSR_GE_Pos 16U /*!< APSR: GE Position */ #define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ /** \brief Union type to access the Interrupt Program Status Register (IPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } IPSR_Type; /* IPSR Register Definitions */ #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ /** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:1; /*!< bit: 9 Reserved */ uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ uint32_t T:1; /*!< bit: 24 Thumb bit */ uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } xPSR_Type; /* xPSR Register Definitions */ #define xPSR_N_Pos 31U /*!< xPSR: N Position */ #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ #define xPSR_C_Pos 29U /*!< xPSR: C Position */ #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ #define xPSR_V_Pos 28U /*!< xPSR: V Position */ #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ #define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ #define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ #define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ #define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ #define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ #define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ #define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ #define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ /** \brief Union type to access the Control Registers (CONTROL). */ typedef union { struct { uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } CONTROL_Type; /* CONTROL Register Definitions */ #define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ #define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ #define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ #define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ /*@} end of group CMSIS_CORE */ /** \ingroup CMSIS_core_register \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) \brief Type definitions for the NVIC Registers @{ */ /** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). */ typedef struct { __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[24U]; __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ uint32_t RESERVED1[24U]; __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[24U]; __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ uint32_t RESERVED3[24U]; __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ uint32_t RESERVED4[56U]; __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ uint32_t RESERVED5[644U]; __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ } NVIC_Type; /* Software Triggered Interrupt Register Definitions */ #define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ #define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ /*@} end of group CMSIS_NVIC */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCB System Control Block (SCB) \brief Type definitions for the System Control Block Registers @{ */ /** \brief Structure type to access the System Control Block (SCB). */ typedef struct { __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ uint32_t RESERVED0[5U]; __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ } SCB_Type; /* SCB CPUID Register Definitions */ #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ /* SCB Interrupt Control State Register Definitions */ #define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ #define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ #define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ #define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ /* SCB Vector Table Offset Register Definitions */ #define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ #define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ /* SCB Application Interrupt and Reset Control Register Definitions */ #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ #define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ #define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ #define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ #define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ /* SCB System Control Register Definitions */ #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ /* SCB Configuration Control Register Definitions */ #define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ #define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ #define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ #define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ #define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ #define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ #define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ #define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ #define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ #define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ /* SCB System Handler Control and State Register Definitions */ #define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ #define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ #define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ #define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ #define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ #define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ #define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ #define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ #define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ #define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ #define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ #define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ #define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ #define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ #define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ #define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ #define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ #define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ #define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ #define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ #define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ #define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ #define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ #define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ #define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ #define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ /* SCB Configurable Fault Status Register Definitions */ #define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ #define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ #define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ #define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ #define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ #define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ /* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ #define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ #define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ #define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ #define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ #define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ #define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ #define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ #define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ #define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ #define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ #define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ /* BusFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ #define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ #define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ #define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ #define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ #define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ #define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ #define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ #define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ #define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ #define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ #define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ #define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ #define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ /* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ #define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ #define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ #define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ #define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ #define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ #define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ #define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ #define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ #define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ #define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ #define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ /* SCB Hard Fault Status Register Definitions */ #define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ #define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ #define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ #define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ #define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ #define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ /* SCB Debug Fault Status Register Definitions */ #define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ #define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ #define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ #define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ #define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ #define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ #define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ #define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ #define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ #define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ /*@} end of group CMSIS_SCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) \brief Type definitions for the System Control and ID Register not in the SCB @{ */ /** \brief Structure type to access the System Control and ID Register not in the SCB. */ typedef struct { uint32_t RESERVED0[1U]; __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ } SCnSCB_Type; /* Interrupt Controller Type Register Definitions */ #define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ #define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ /* Auxiliary Control Register Definitions */ #define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ #define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ #define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ #define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ #define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ #define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ #define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ #define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ #define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ #define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ /*@} end of group CMSIS_SCnotSCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SysTick System Tick Timer (SysTick) \brief Type definitions for the System Timer Registers. @{ */ /** \brief Structure type to access the System Timer (SysTick). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; /* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ /* SysTick Calibration Register Definitions */ #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ /*@} end of group CMSIS_SysTick */ /** \ingroup CMSIS_core_register \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) \brief Type definitions for the Instrumentation Trace Macrocell (ITM) @{ */ /** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). */ typedef struct { __OM union { __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ uint32_t RESERVED0[864U]; __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ uint32_t RESERVED1[15U]; __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ uint32_t RESERVED2[15U]; __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ uint32_t RESERVED3[32U]; uint32_t RESERVED4[43U]; __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ uint32_t RESERVED5[6U]; __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ } ITM_Type; /* ITM Trace Privilege Register Definitions */ #define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ #define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ /* ITM Trace Control Register Definitions */ #define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ #define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ #define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ #define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ #define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ #define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ #define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ #define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ #define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ #define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ #define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ #define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ #define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ #define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ #define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ #define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ #define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ #define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ /* ITM Lock Status Register Definitions */ #define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ #define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ #define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ #define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ #define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ #define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ /*@}*/ /* end of group CMSIS_ITM */ /** \ingroup CMSIS_core_register \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) \brief Type definitions for the Data Watchpoint and Trace (DWT) @{ */ /** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ uint32_t RESERVED0[1U]; __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ uint32_t RESERVED1[1U]; __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ uint32_t RESERVED2[1U]; __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ } DWT_Type; /* DWT Control Register Definitions */ #define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ #define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ #define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ #define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ #define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ #define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ #define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ #define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ #define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ #define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ #define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ #define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ #define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ #define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ #define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ #define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ #define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ #define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ #define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ #define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ #define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ #define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ #define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ #define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ #define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ #define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ #define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ #define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ #define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ #define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ #define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ #define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ #define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ #define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ #define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ #define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ /* DWT CPI Count Register Definitions */ #define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ #define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ /* DWT Exception Overhead Count Register Definitions */ #define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ #define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ /* DWT Sleep Count Register Definitions */ #define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ #define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ /* DWT LSU Count Register Definitions */ #define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ #define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ /* DWT Folded-instruction Count Register Definitions */ #define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ #define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ /* DWT Comparator Mask Register Definitions */ #define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ #define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ /* DWT Comparator Function Register Definitions */ #define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ #define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ #define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ #define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ #define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ #define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ #define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ #define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ #define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ #define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ #define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ #define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ #define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ #define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ #define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ #define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ #define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ #define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ /*@}*/ /* end of group CMSIS_DWT */ /** \ingroup CMSIS_core_register \defgroup CMSIS_TPI Trace Port Interface (TPI) \brief Type definitions for the Trace Port Interface (TPI) @{ */ /** \brief Structure type to access the Trace Port Interface Register (TPI). */ typedef struct { __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ uint32_t RESERVED1[55U]; __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ uint32_t RESERVED2[131U]; __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ uint32_t RESERVED3[759U]; __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ uint32_t RESERVED4[1U]; __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ uint32_t RESERVED5[39U]; __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ uint32_t RESERVED7[8U]; __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ } TPI_Type; /* TPI Asynchronous Clock Prescaler Register Definitions */ #define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ #define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ /* TPI Selected Pin Protocol Register Definitions */ #define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ #define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ /* TPI Formatter and Flush Status Register Definitions */ #define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ #define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ #define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ #define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ #define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ #define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ #define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ #define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ /* TPI Formatter and Flush Control Register Definitions */ #define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ #define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ #define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ #define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ /* TPI TRIGGER Register Definitions */ #define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ #define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ /* TPI Integration ETM Data Register Definitions (FIFO0) */ #define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ #define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ #define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ #define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ #define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ #define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ #define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ #define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ #define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ #define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ #define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ #define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ #define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ #define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ /* TPI ITATBCTR2 Register Definitions */ #define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ #define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ #define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ #define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ /* TPI Integration ITM Data Register Definitions (FIFO1) */ #define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ #define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ #define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ #define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ #define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ #define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ #define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ #define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ #define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ #define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ #define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ #define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ #define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ #define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ /* TPI ITATBCTR0 Register Definitions */ #define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ #define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ #define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ #define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ /* TPI Integration Mode Control Register Definitions */ #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ #define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ #define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ #define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ #define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ #define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ #define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ #define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ #define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ #define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ #define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ #define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ #define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ #define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ #define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ #define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ /*@}*/ /* end of group CMSIS_TPI */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) /** \ingroup CMSIS_core_register \defgroup CMSIS_MPU Memory Protection Unit (MPU) \brief Type definitions for the Memory Protection Unit (MPU) @{ */ /** \brief Structure type to access the Memory Protection Unit (MPU). */ typedef struct { __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ } MPU_Type; #define MPU_TYPE_RALIASES 4U /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ #define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ #define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ #define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ #define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ /* MPU Control Register Definitions */ #define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ #define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ #define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ #define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ #define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ #define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ /* MPU Region Number Register Definitions */ #define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ #define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ /* MPU Region Base Address Register Definitions */ #define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ #define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ #define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ #define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ #define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ #define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ /* MPU Region Attribute and Size Register Definitions */ #define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ #define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ #define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ #define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ #define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ #define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ #define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ #define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ #define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ #define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ #define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ #define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ #define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ #define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ #define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ #define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ #define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ #define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ #define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ #define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ /*@} end of group CMSIS_MPU */ #endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ /** \ingroup CMSIS_core_register \defgroup CMSIS_FPU Floating Point Unit (FPU) \brief Type definitions for the Floating Point Unit (FPU) @{ */ /** \brief Structure type to access the Floating Point Unit (FPU). */ typedef struct { uint32_t RESERVED0[1U]; __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ } FPU_Type; /* Floating-Point Context Control Register Definitions */ #define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ #define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ #define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ #define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ #define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ #define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ #define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ #define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ #define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ #define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ #define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ #define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ #define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ #define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ #define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ #define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ #define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ #define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ /* Floating-Point Context Address Register Definitions */ #define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ #define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ /* Floating-Point Default Status Control Register Definitions */ #define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ #define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ #define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ #define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ #define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ #define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ #define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ #define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ /* Media and FP Feature Register 0 Definitions */ #define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ #define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ #define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ #define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ #define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ #define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ #define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ #define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ #define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ #define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ #define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ #define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ #define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ #define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ #define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ #define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ /* Media and FP Feature Register 1 Definitions */ #define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ #define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ #define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ #define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ #define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ #define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ #define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ #define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ /* Media and FP Feature Register 2 Definitions */ #define FPU_MVFR2_VFP_Misc_Pos 4U /*!< MVFR2: VFP Misc bits Position */ #define FPU_MVFR2_VFP_Misc_Msk (0xFUL << FPU_MVFR2_VFP_Misc_Pos) /*!< MVFR2: VFP Misc bits Mask */ /*@} end of group CMSIS_FPU */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) \brief Type definitions for the Core Debug Registers @{ */ /** \brief Structure type to access the Core Debug Register (CoreDebug). */ typedef struct { __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ } CoreDebug_Type; /* Debug Halting Control and Status Register Definitions */ #define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ #define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ #define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ #define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ #define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ #define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ #define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ #define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ #define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ #define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ #define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ #define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ #define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ #define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ #define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ #define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ #define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ #define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ #define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ #define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ #define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ #define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ /* Debug Core Register Selector Register Definitions */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ #define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ /* Debug Exception and Monitor Control Register Definitions */ #define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ #define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ #define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ #define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ #define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ #define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ #define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ #define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ #define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ #define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ #define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ #define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ #define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ #define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ #define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ #define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ #define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ #define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ #define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ #define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ #define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ #define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ #define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ #define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ #define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ #define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ /*@} end of group CMSIS_CoreDebug */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_bitfield Core register bit field macros \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). @{ */ /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_base Core Definitions \brief Definitions for base addresses, unions, and structures. @{ */ /* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ #endif #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ /*@} */ /******************************************************************************* * Hardware Abstraction Layer Core Function Interface contains: - Core NVIC Functions - Core SysTick Functions - Core Debug Functions - Core Register Access Functions ******************************************************************************/ /** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference */ /* ########################## NVIC functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_NVICFunctions NVIC Functions \brief Functions that manage interrupts and exceptions via the NVIC. @{ */ #ifdef CMSIS_NVIC_VIRTUAL #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" #endif #include CMSIS_NVIC_VIRTUAL_HEADER_FILE #else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ #define NVIC_GetActive __NVIC_GetActive #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ #ifdef CMSIS_VECTAB_VIRTUAL #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" #endif #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE #else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ #define NVIC_USER_IRQ_OFFSET 16 /* The following EXC_RETURN values are saved the LR on exception entry */ #define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ #define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ #define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ #define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ #define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ #define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ /** \brief Set Priority Grouping \details Sets the priority grouping field using the required unlock sequence. The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Priority grouping field. */ __STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ reg_value = SCB->AIRCR; /* read old register configuration */ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB->AIRCR = reg_value; } /** \brief Get Priority Grouping \details Reads the priority grouping field from the NVIC Interrupt Controller. \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ __STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) { return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); } /** \brief Enable Interrupt \details Enables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { __COMPILER_BARRIER(); NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __COMPILER_BARRIER(); } } /** \brief Get Interrupt Enable status \details Returns a device specific interrupt enable status from the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt \details Disables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } } /** \brief Get Pending Interrupt \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt \details Sets the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt \details Clears the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Priority \details Sets the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every processor exception. */ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } /** \brief Get Interrupt Priority \details Reads the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } /** \brief Encode Priority \details Encodes the priority for an interrupt with the given priority group, preemptive priority value, and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Used priority group. \param [in] PreemptPriority Preemptive priority value (starting from 0). \param [in] SubPriority Subpriority value (starting from 0). \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). */ __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); return ( ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) ); } /** \brief Decode Priority \details Decodes an interrupt priority value with a given priority group to preemptive priority value and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). \param [in] PriorityGroup Used priority group. \param [out] pPreemptPriority Preemptive priority value (starting from 0). \param [out] pSubPriority Subpriority value (starting from 0). */ __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); } /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. VTOR must been relocated to SRAM before. \param [in] IRQn Interrupt number \param [in] vector Address of interrupt handler function */ __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { uint32_t vectors = (uint32_t )SCB->VTOR; (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; /* ARM Application Note 321 states that the M4 does not require the architectural barrier */ } /** \brief Get Interrupt Vector \details Reads an interrupt vector from interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Address of interrupt handler function */ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) { uint32_t vectors = (uint32_t )SCB->VTOR; return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); } /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ __DSB(); /* Ensure completion of memory access */ for(;;) /* wait until reset */ { __NOP(); } } /*@} end of CMSIS_Core_NVICFunctions */ /* ########################## MPU functions #################################### */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #include "mpu_armv7.h" #endif /* ########################## FPU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_FpuFunctions FPU Functions \brief Function that provides FPU type. @{ */ /** \brief get FPU type \details returns the FPU type \returns - \b 0: No FPU - \b 1: Single precision FPU - \b 2: Double + Single precision FPU */ __STATIC_INLINE uint32_t SCB_GetFPUType(void) { uint32_t mvfr0; mvfr0 = FPU->MVFR0; if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) { return 1U; /* Single precision FPU */ } else { return 0U; /* No FPU */ } } /*@} end of CMSIS_Core_FpuFunctions */ /* ################################## SysTick function ############################################ */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SysTickFunctions SysTick Functions \brief Functions that configure the System. @{ */ #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #endif /*@} end of CMSIS_Core_SysTickFunctions */ /* ##################################### Debug In/Output function ########################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_core_DebugFunctions ITM Functions \brief Functions that access the ITM debug interface. @{ */ extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ #define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ /** \brief ITM Send Character \details Transmits a character via the ITM channel 0, and \li Just returns when no debugger is connected that has booked the output. \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. \param [in] ch Character to transmit. \returns Character to transmit. */ __STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) { if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ { while (ITM->PORT[0U].u32 == 0UL) { __NOP(); } ITM->PORT[0U].u8 = (uint8_t)ch; } return (ch); } /** \brief ITM Receive Character \details Inputs a character via the external variable \ref ITM_RxBuffer. \return Received character. \return -1 No character pending. */ __STATIC_INLINE int32_t ITM_ReceiveChar (void) { int32_t ch = -1; /* no character available */ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { ch = ITM_RxBuffer; ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ } return (ch); } /** \brief ITM Check Character \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. \return 0 No character available. \return 1 Character available. */ __STATIC_INLINE int32_t ITM_CheckChar (void) { if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { return (0); /* no character available */ } else { return (1); /* character available */ } } /*@} end of CMSIS_core_DebugFunctions */ #ifdef __cplusplus } #endif #endif /* __CORE_CM4_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ ================================================ FILE: 3rd_party/CMSIS/Include/core_cm7.h ================================================ /**************************************************************************//** * @file core_cm7.h * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File * @version V5.1.1 * @date 28. March 2019 ******************************************************************************/ /* * Copyright (c) 2009-2019 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_CM7_H_GENERIC #define __CORE_CM7_H_GENERIC #include #ifdef __cplusplus extern "C" { #endif /** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions CMSIS violates the following MISRA-C:2004 rules: \li Required Rule 8.5, object/function definition in header file.
Function definitions in header files are used to allow 'inlining'. \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
Unions are used for effective representation of core registers. \li Advisory Rule 19.7, Function-like macro defined.
Function-like macros are used to allow more efficient code. */ /******************************************************************************* * CMSIS definitions ******************************************************************************/ /** \ingroup Cortex_M7 @{ */ #include "cmsis_version.h" /* CMSIS CM7 definitions */ #define __CM7_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ #define __CM7_CMSIS_VERSION_SUB ( __CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \ __CM7_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (7U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. */ #if defined ( __CC_ARM ) #if defined __TARGET_FPU_VFP #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined __ARM_FP #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __TASKING__ ) #if defined __FPU_VFP__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __CSMC__ ) #if ( __CSMC__ & 0x400U) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #endif #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ #ifdef __cplusplus } #endif #endif /* __CORE_CM7_H_GENERIC */ #ifndef __CMSIS_GENERIC #ifndef __CORE_CM7_H_DEPENDANT #define __CORE_CM7_H_DEPENDANT #ifdef __cplusplus extern "C" { #endif /* check device defines and use defaults */ #if defined __CHECK_DEVICE_DEFINES #ifndef __CM7_REV #define __CM7_REV 0x0000U #warning "__CM7_REV not defined in device header file; using default!" #endif #ifndef __FPU_PRESENT #define __FPU_PRESENT 0U #warning "__FPU_PRESENT not defined in device header file; using default!" #endif #ifndef __MPU_PRESENT #define __MPU_PRESENT 0U #warning "__MPU_PRESENT not defined in device header file; using default!" #endif #ifndef __ICACHE_PRESENT #define __ICACHE_PRESENT 0U #warning "__ICACHE_PRESENT not defined in device header file; using default!" #endif #ifndef __DCACHE_PRESENT #define __DCACHE_PRESENT 0U #warning "__DCACHE_PRESENT not defined in device header file; using default!" #endif #ifndef __DTCM_PRESENT #define __DTCM_PRESENT 0U #warning "__DTCM_PRESENT not defined in device header file; using default!" #endif #ifndef __NVIC_PRIO_BITS #define __NVIC_PRIO_BITS 3U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif #ifndef __Vendor_SysTickConfig #define __Vendor_SysTickConfig 0U #warning "__Vendor_SysTickConfig not defined in device header file; using default!" #endif #endif /* IO definitions (access restrictions to peripheral registers) */ /** \defgroup CMSIS_glob_defs CMSIS Global Defines IO Type Qualifiers are used \li to specify the access to peripheral variables. \li for automatic generation of peripheral register debug information. */ #ifdef __cplusplus #define __I volatile /*!< Defines 'read only' permissions */ #else #define __I volatile const /*!< Defines 'read only' permissions */ #endif #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */ /* following defines should be used for structure members */ #define __IM volatile const /*! Defines 'read only' structure member permissions */ #define __OM volatile /*! Defines 'write only' structure member permissions */ #define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group Cortex_M7 */ /******************************************************************************* * Register Abstraction Core Register contain: - Core Register - Core NVIC Register - Core SCB Register - Core SysTick Register - Core Debug Register - Core MPU Register - Core FPU Register ******************************************************************************/ /** \defgroup CMSIS_core_register Defines and Type Definitions \brief Type definitions and defines for Cortex-M processor based devices. */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CORE Status and Control Registers \brief Core Register type definitions. @{ */ /** \brief Union type to access the Application Program Status Register (APSR). */ typedef union { struct { uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } APSR_Type; /* APSR Register Definitions */ #define APSR_N_Pos 31U /*!< APSR: N Position */ #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ #define APSR_Z_Pos 30U /*!< APSR: Z Position */ #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ #define APSR_C_Pos 29U /*!< APSR: C Position */ #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ #define APSR_V_Pos 28U /*!< APSR: V Position */ #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ #define APSR_Q_Pos 27U /*!< APSR: Q Position */ #define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ #define APSR_GE_Pos 16U /*!< APSR: GE Position */ #define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ /** \brief Union type to access the Interrupt Program Status Register (IPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } IPSR_Type; /* IPSR Register Definitions */ #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ /** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:1; /*!< bit: 9 Reserved */ uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ uint32_t T:1; /*!< bit: 24 Thumb bit */ uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } xPSR_Type; /* xPSR Register Definitions */ #define xPSR_N_Pos 31U /*!< xPSR: N Position */ #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ #define xPSR_C_Pos 29U /*!< xPSR: C Position */ #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ #define xPSR_V_Pos 28U /*!< xPSR: V Position */ #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ #define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ #define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ #define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ #define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ #define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ #define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ #define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ #define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ /** \brief Union type to access the Control Registers (CONTROL). */ typedef union { struct { uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } CONTROL_Type; /* CONTROL Register Definitions */ #define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ #define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ #define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ #define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ /*@} end of group CMSIS_CORE */ /** \ingroup CMSIS_core_register \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) \brief Type definitions for the NVIC Registers @{ */ /** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). */ typedef struct { __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[24U]; __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ uint32_t RESERVED1[24U]; __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[24U]; __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ uint32_t RESERVED3[24U]; __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ uint32_t RESERVED4[56U]; __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ uint32_t RESERVED5[644U]; __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ } NVIC_Type; /* Software Triggered Interrupt Register Definitions */ #define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ #define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ /*@} end of group CMSIS_NVIC */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCB System Control Block (SCB) \brief Type definitions for the System Control Block Registers @{ */ /** \brief Structure type to access the System Control Block (SCB). */ typedef struct { __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ __IM uint32_t ID_MFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ uint32_t RESERVED0[1U]; __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ uint32_t RESERVED3[93U]; __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ uint32_t RESERVED4[15U]; __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ uint32_t RESERVED5[1U]; __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ uint32_t RESERVED6[1U]; __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ uint32_t RESERVED7[6U]; __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ uint32_t RESERVED8[1U]; __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ } SCB_Type; /* SCB CPUID Register Definitions */ #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ /* SCB Interrupt Control State Register Definitions */ #define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ #define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ #define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ #define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ /* SCB Vector Table Offset Register Definitions */ #define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ #define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ /* SCB Application Interrupt and Reset Control Register Definitions */ #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ #define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ #define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ #define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ #define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ /* SCB System Control Register Definitions */ #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ /* SCB Configuration Control Register Definitions */ #define SCB_CCR_BP_Pos 18U /*!< SCB CCR: Branch prediction enable bit Position */ #define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: Branch prediction enable bit Mask */ #define SCB_CCR_IC_Pos 17U /*!< SCB CCR: Instruction cache enable bit Position */ #define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: Instruction cache enable bit Mask */ #define SCB_CCR_DC_Pos 16U /*!< SCB CCR: Cache enable bit Position */ #define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: Cache enable bit Mask */ #define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ #define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ #define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ #define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ #define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ #define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ #define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ #define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ #define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ #define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ /* SCB System Handler Control and State Register Definitions */ #define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ #define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ #define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ #define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ #define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ #define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ #define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ #define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ #define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ #define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ #define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ #define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ #define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ #define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ #define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ #define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ #define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ #define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ #define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ #define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ #define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ #define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ #define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ #define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ #define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ #define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ /* SCB Configurable Fault Status Register Definitions */ #define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ #define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ #define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ #define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ #define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ #define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ /* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ #define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ #define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ #define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ #define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ #define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ #define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ #define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ #define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ #define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ #define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ #define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ /* BusFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ #define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ #define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ #define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ #define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ #define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ #define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ #define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ #define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ #define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ #define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ #define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ #define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ #define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ /* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ #define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ #define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ #define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ #define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ #define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ #define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ #define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ #define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ #define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ #define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ #define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ /* SCB Hard Fault Status Register Definitions */ #define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ #define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ #define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ #define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ #define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ #define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ /* SCB Debug Fault Status Register Definitions */ #define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ #define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ #define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ #define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ #define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ #define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ #define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ #define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ #define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ #define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ /* SCB Cache Level ID Register Definitions */ #define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ #define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ #define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ #define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ /* SCB Cache Type Register Definitions */ #define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ #define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ #define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ #define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ #define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ #define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ #define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ #define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ #define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ #define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ /* SCB Cache Size ID Register Definitions */ #define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ #define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ #define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ #define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ #define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ #define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ #define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ #define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ #define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ #define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ #define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ #define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ #define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ #define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ /* SCB Cache Size Selection Register Definitions */ #define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ #define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ #define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ #define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ /* SCB Software Triggered Interrupt Register Definitions */ #define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ #define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ /* SCB D-Cache Invalidate by Set-way Register Definitions */ #define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ #define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ #define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ #define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ /* SCB D-Cache Clean by Set-way Register Definitions */ #define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ #define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ #define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ #define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ /* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ #define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ #define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ #define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ #define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ /* Instruction Tightly-Coupled Memory Control Register Definitions */ #define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ #define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ #define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ #define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ #define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ #define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ #define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ #define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ /* Data Tightly-Coupled Memory Control Register Definitions */ #define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ #define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ #define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ #define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ #define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ #define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ #define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ #define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ /* AHBP Control Register Definitions */ #define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ #define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ #define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ #define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ /* L1 Cache Control Register Definitions */ #define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ #define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ #define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ #define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ #define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ #define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ /* AHBS Control Register Definitions */ #define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ #define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ #define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ #define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ #define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ #define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ /* Auxiliary Bus Fault Status Register Definitions */ #define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ #define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ #define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ #define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ #define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ #define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ #define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ #define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ #define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ #define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ #define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ #define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ /*@} end of group CMSIS_SCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) \brief Type definitions for the System Control and ID Register not in the SCB @{ */ /** \brief Structure type to access the System Control and ID Register not in the SCB. */ typedef struct { uint32_t RESERVED0[1U]; __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ } SCnSCB_Type; /* Interrupt Controller Type Register Definitions */ #define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ #define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ /* Auxiliary Control Register Definitions */ #define SCnSCB_ACTLR_DISDYNADD_Pos 26U /*!< ACTLR: DISDYNADD Position */ #define SCnSCB_ACTLR_DISDYNADD_Msk (1UL << SCnSCB_ACTLR_DISDYNADD_Pos) /*!< ACTLR: DISDYNADD Mask */ #define SCnSCB_ACTLR_DISISSCH1_Pos 21U /*!< ACTLR: DISISSCH1 Position */ #define SCnSCB_ACTLR_DISISSCH1_Msk (0x1FUL << SCnSCB_ACTLR_DISISSCH1_Pos) /*!< ACTLR: DISISSCH1 Mask */ #define SCnSCB_ACTLR_DISDI_Pos 16U /*!< ACTLR: DISDI Position */ #define SCnSCB_ACTLR_DISDI_Msk (0x1FUL << SCnSCB_ACTLR_DISDI_Pos) /*!< ACTLR: DISDI Mask */ #define SCnSCB_ACTLR_DISCRITAXIRUR_Pos 15U /*!< ACTLR: DISCRITAXIRUR Position */ #define SCnSCB_ACTLR_DISCRITAXIRUR_Msk (1UL << SCnSCB_ACTLR_DISCRITAXIRUR_Pos) /*!< ACTLR: DISCRITAXIRUR Mask */ #define SCnSCB_ACTLR_DISBTACALLOC_Pos 14U /*!< ACTLR: DISBTACALLOC Position */ #define SCnSCB_ACTLR_DISBTACALLOC_Msk (1UL << SCnSCB_ACTLR_DISBTACALLOC_Pos) /*!< ACTLR: DISBTACALLOC Mask */ #define SCnSCB_ACTLR_DISBTACREAD_Pos 13U /*!< ACTLR: DISBTACREAD Position */ #define SCnSCB_ACTLR_DISBTACREAD_Msk (1UL << SCnSCB_ACTLR_DISBTACREAD_Pos) /*!< ACTLR: DISBTACREAD Mask */ #define SCnSCB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ #define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ #define SCnSCB_ACTLR_DISRAMODE_Pos 11U /*!< ACTLR: DISRAMODE Position */ #define SCnSCB_ACTLR_DISRAMODE_Msk (1UL << SCnSCB_ACTLR_DISRAMODE_Pos) /*!< ACTLR: DISRAMODE Mask */ #define SCnSCB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ #define SCnSCB_ACTLR_FPEXCODIS_Msk (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ #define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ #define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ #define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ #define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ /*@} end of group CMSIS_SCnotSCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SysTick System Tick Timer (SysTick) \brief Type definitions for the System Timer Registers. @{ */ /** \brief Structure type to access the System Timer (SysTick). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; /* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ /* SysTick Calibration Register Definitions */ #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ /*@} end of group CMSIS_SysTick */ /** \ingroup CMSIS_core_register \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) \brief Type definitions for the Instrumentation Trace Macrocell (ITM) @{ */ /** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). */ typedef struct { __OM union { __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ uint32_t RESERVED0[864U]; __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ uint32_t RESERVED1[15U]; __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ uint32_t RESERVED2[15U]; __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ uint32_t RESERVED3[32U]; uint32_t RESERVED4[43U]; __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ uint32_t RESERVED5[6U]; __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ } ITM_Type; /* ITM Trace Privilege Register Definitions */ #define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ #define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ /* ITM Trace Control Register Definitions */ #define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ #define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ #define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ #define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ #define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ #define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ #define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ #define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ #define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ #define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ #define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ #define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ #define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ #define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ #define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ #define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ #define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ #define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ /* ITM Lock Status Register Definitions */ #define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ #define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ #define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ #define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ #define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ #define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ /*@}*/ /* end of group CMSIS_ITM */ /** \ingroup CMSIS_core_register \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) \brief Type definitions for the Data Watchpoint and Trace (DWT) @{ */ /** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ uint32_t RESERVED0[1U]; __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ uint32_t RESERVED1[1U]; __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ uint32_t RESERVED2[1U]; __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ uint32_t RESERVED3[981U]; __OM uint32_t LAR; /*!< Offset: 0xFB0 ( W) Lock Access Register */ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ } DWT_Type; /* DWT Control Register Definitions */ #define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ #define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ #define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ #define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ #define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ #define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ #define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ #define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ #define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ #define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ #define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ #define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ #define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ #define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ #define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ #define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ #define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ #define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ #define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ #define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ #define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ #define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ #define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ #define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ #define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ #define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ #define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ #define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ #define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ #define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ #define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ #define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ #define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ #define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ #define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ #define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ /* DWT CPI Count Register Definitions */ #define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ #define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ /* DWT Exception Overhead Count Register Definitions */ #define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ #define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ /* DWT Sleep Count Register Definitions */ #define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ #define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ /* DWT LSU Count Register Definitions */ #define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ #define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ /* DWT Folded-instruction Count Register Definitions */ #define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ #define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ /* DWT Comparator Mask Register Definitions */ #define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ #define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ /* DWT Comparator Function Register Definitions */ #define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ #define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ #define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ #define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ #define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ #define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ #define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ #define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ #define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ #define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ #define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ #define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ #define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ #define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ #define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ #define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ #define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ #define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ /*@}*/ /* end of group CMSIS_DWT */ /** \ingroup CMSIS_core_register \defgroup CMSIS_TPI Trace Port Interface (TPI) \brief Type definitions for the Trace Port Interface (TPI) @{ */ /** \brief Structure type to access the Trace Port Interface Register (TPI). */ typedef struct { __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ uint32_t RESERVED1[55U]; __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ uint32_t RESERVED2[131U]; __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ uint32_t RESERVED3[759U]; __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ uint32_t RESERVED4[1U]; __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ uint32_t RESERVED5[39U]; __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ uint32_t RESERVED7[8U]; __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ } TPI_Type; /* TPI Asynchronous Clock Prescaler Register Definitions */ #define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ #define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ /* TPI Selected Pin Protocol Register Definitions */ #define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ #define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ /* TPI Formatter and Flush Status Register Definitions */ #define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ #define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ #define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ #define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ #define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ #define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ #define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ #define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ /* TPI Formatter and Flush Control Register Definitions */ #define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ #define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ #define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ #define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ /* TPI TRIGGER Register Definitions */ #define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ #define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ /* TPI Integration ETM Data Register Definitions (FIFO0) */ #define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ #define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ #define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ #define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ #define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ #define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ #define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ #define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ #define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ #define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ #define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ #define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ #define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ #define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ /* TPI ITATBCTR2 Register Definitions */ #define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ #define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ #define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ #define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ /* TPI Integration ITM Data Register Definitions (FIFO1) */ #define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ #define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ #define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ #define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ #define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ #define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ #define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ #define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ #define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ #define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ #define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ #define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ #define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ #define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ /* TPI ITATBCTR0 Register Definitions */ #define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ #define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ #define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ #define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ /* TPI Integration Mode Control Register Definitions */ #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ #define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ #define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ #define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ #define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ #define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ #define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ #define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ #define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ #define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ #define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ #define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ #define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ #define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ #define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ #define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ /*@}*/ /* end of group CMSIS_TPI */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) /** \ingroup CMSIS_core_register \defgroup CMSIS_MPU Memory Protection Unit (MPU) \brief Type definitions for the Memory Protection Unit (MPU) @{ */ /** \brief Structure type to access the Memory Protection Unit (MPU). */ typedef struct { __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ } MPU_Type; #define MPU_TYPE_RALIASES 4U /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ #define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ #define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ #define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ #define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ /* MPU Control Register Definitions */ #define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ #define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ #define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ #define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ #define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ #define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ /* MPU Region Number Register Definitions */ #define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ #define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ /* MPU Region Base Address Register Definitions */ #define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ #define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ #define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ #define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ #define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ #define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ /* MPU Region Attribute and Size Register Definitions */ #define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ #define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ #define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ #define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ #define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ #define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ #define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ #define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ #define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ #define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ #define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ #define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ #define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ #define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ #define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ #define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ #define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ #define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ #define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ #define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ /*@} end of group CMSIS_MPU */ #endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ /** \ingroup CMSIS_core_register \defgroup CMSIS_FPU Floating Point Unit (FPU) \brief Type definitions for the Floating Point Unit (FPU) @{ */ /** \brief Structure type to access the Floating Point Unit (FPU). */ typedef struct { uint32_t RESERVED0[1U]; __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ } FPU_Type; /* Floating-Point Context Control Register Definitions */ #define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ #define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ #define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ #define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ #define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ #define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ #define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ #define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ #define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ #define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ #define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ #define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ #define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ #define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ #define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ #define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ #define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ #define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ /* Floating-Point Context Address Register Definitions */ #define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ #define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ /* Floating-Point Default Status Control Register Definitions */ #define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ #define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ #define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ #define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ #define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ #define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ #define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ #define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ /* Media and FP Feature Register 0 Definitions */ #define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ #define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ #define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ #define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ #define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ #define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ #define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ #define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ #define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ #define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ #define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ #define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ #define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ #define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ #define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ #define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ /* Media and FP Feature Register 1 Definitions */ #define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ #define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ #define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ #define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ #define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ #define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ #define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ #define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ /* Media and FP Feature Register 2 Definitions */ #define FPU_MVFR2_VFP_Misc_Pos 4U /*!< MVFR2: VFP Misc bits Position */ #define FPU_MVFR2_VFP_Misc_Msk (0xFUL << FPU_MVFR2_VFP_Misc_Pos) /*!< MVFR2: VFP Misc bits Mask */ /*@} end of group CMSIS_FPU */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) \brief Type definitions for the Core Debug Registers @{ */ /** \brief Structure type to access the Core Debug Register (CoreDebug). */ typedef struct { __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ } CoreDebug_Type; /* Debug Halting Control and Status Register Definitions */ #define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ #define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ #define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ #define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ #define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ #define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ #define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ #define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ #define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ #define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ #define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ #define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ #define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ #define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ #define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ #define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ #define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ #define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ #define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ #define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ #define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ #define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ /* Debug Core Register Selector Register Definitions */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ #define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ /* Debug Exception and Monitor Control Register Definitions */ #define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ #define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ #define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ #define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ #define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ #define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ #define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ #define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ #define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ #define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ #define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ #define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ #define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ #define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ #define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ #define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ #define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ #define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ #define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ #define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ #define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ #define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ #define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ #define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ #define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ #define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ /*@} end of group CMSIS_CoreDebug */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_bitfield Core register bit field macros \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). @{ */ /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_base Core Definitions \brief Definitions for base addresses, unions, and structures. @{ */ /* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ #endif #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ /*@} */ /******************************************************************************* * Hardware Abstraction Layer Core Function Interface contains: - Core NVIC Functions - Core SysTick Functions - Core Debug Functions - Core Register Access Functions ******************************************************************************/ /** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference */ /* ########################## NVIC functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_NVICFunctions NVIC Functions \brief Functions that manage interrupts and exceptions via the NVIC. @{ */ #ifdef CMSIS_NVIC_VIRTUAL #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" #endif #include CMSIS_NVIC_VIRTUAL_HEADER_FILE #else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ #define NVIC_GetActive __NVIC_GetActive #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ #ifdef CMSIS_VECTAB_VIRTUAL #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" #endif #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE #else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ #define NVIC_USER_IRQ_OFFSET 16 /* The following EXC_RETURN values are saved the LR on exception entry */ #define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ #define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ #define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ #define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ #define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ #define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ /** \brief Set Priority Grouping \details Sets the priority grouping field using the required unlock sequence. The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Priority grouping field. */ __STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ reg_value = SCB->AIRCR; /* read old register configuration */ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB->AIRCR = reg_value; } /** \brief Get Priority Grouping \details Reads the priority grouping field from the NVIC Interrupt Controller. \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ __STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) { return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); } /** \brief Enable Interrupt \details Enables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { __COMPILER_BARRIER(); NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __COMPILER_BARRIER(); } } /** \brief Get Interrupt Enable status \details Returns a device specific interrupt enable status from the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt \details Disables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } } /** \brief Get Pending Interrupt \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt \details Sets the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt \details Clears the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Priority \details Sets the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every processor exception. */ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } /** \brief Get Interrupt Priority \details Reads the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } /** \brief Encode Priority \details Encodes the priority for an interrupt with the given priority group, preemptive priority value, and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Used priority group. \param [in] PreemptPriority Preemptive priority value (starting from 0). \param [in] SubPriority Subpriority value (starting from 0). \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). */ __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); return ( ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) ); } /** \brief Decode Priority \details Decodes an interrupt priority value with a given priority group to preemptive priority value and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). \param [in] PriorityGroup Used priority group. \param [out] pPreemptPriority Preemptive priority value (starting from 0). \param [out] pSubPriority Subpriority value (starting from 0). */ __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); } /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. VTOR must been relocated to SRAM before. \param [in] IRQn Interrupt number \param [in] vector Address of interrupt handler function */ __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { uint32_t vectors = (uint32_t )SCB->VTOR; (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; __DSB(); } /** \brief Get Interrupt Vector \details Reads an interrupt vector from interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Address of interrupt handler function */ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) { uint32_t vectors = (uint32_t )SCB->VTOR; return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); } /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ __DSB(); /* Ensure completion of memory access */ for(;;) /* wait until reset */ { __NOP(); } } /*@} end of CMSIS_Core_NVICFunctions */ /* ########################## MPU functions #################################### */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #include "mpu_armv7.h" #endif /* ########################## FPU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_FpuFunctions FPU Functions \brief Function that provides FPU type. @{ */ /** \brief get FPU type \details returns the FPU type \returns - \b 0: No FPU - \b 1: Single precision FPU - \b 2: Double + Single precision FPU */ __STATIC_INLINE uint32_t SCB_GetFPUType(void) { uint32_t mvfr0; mvfr0 = SCB->MVFR0; if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) { return 2U; /* Double + Single precision FPU */ } else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) { return 1U; /* Single precision FPU */ } else { return 0U; /* No FPU */ } } /*@} end of CMSIS_Core_FpuFunctions */ /* ########################## Cache functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_CacheFunctions Cache Functions \brief Functions that configure Instruction and Data cache. @{ */ /* Cache Size ID Register Macros */ #define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos) #define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) #define __SCB_DCACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ #define __SCB_ICACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ /** \brief Enable I-Cache \details Turns on I-Cache */ __STATIC_FORCEINLINE void SCB_EnableICache (void) { #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) if (SCB->CCR & SCB_CCR_IC_Msk) return; /* return if ICache is already enabled */ __DSB(); __ISB(); SCB->ICIALLU = 0UL; /* invalidate I-Cache */ __DSB(); __ISB(); SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */ __DSB(); __ISB(); #endif } /** \brief Disable I-Cache \details Turns off I-Cache */ __STATIC_FORCEINLINE void SCB_DisableICache (void) { #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) __DSB(); __ISB(); SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */ SCB->ICIALLU = 0UL; /* invalidate I-Cache */ __DSB(); __ISB(); #endif } /** \brief Invalidate I-Cache \details Invalidates I-Cache */ __STATIC_FORCEINLINE void SCB_InvalidateICache (void) { #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) __DSB(); __ISB(); SCB->ICIALLU = 0UL; __DSB(); __ISB(); #endif } /** \brief I-Cache Invalidate by address \details Invalidates I-Cache for the given address. I-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. I-Cache memory blocks which are part of given address + given size are invalidated. \param[in] addr address \param[in] isize size of memory block (in number of bytes) */ __STATIC_FORCEINLINE void SCB_InvalidateICache_by_Addr (void *addr, int32_t isize) { #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) if ( isize > 0 ) { int32_t op_size = isize + (((uint32_t)addr) & (__SCB_ICACHE_LINE_SIZE - 1U)); uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_ICACHE_LINE_SIZE - 1U) */; __DSB(); do { SCB->ICIMVAU = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ op_addr += __SCB_ICACHE_LINE_SIZE; op_size -= __SCB_ICACHE_LINE_SIZE; } while ( op_size > 0 ); __DSB(); __ISB(); } #endif } /** \brief Enable D-Cache \details Turns on D-Cache */ __STATIC_FORCEINLINE void SCB_EnableDCache (void) { #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) uint32_t ccsidr; uint32_t sets; uint32_t ways; if (SCB->CCR & SCB_CCR_DC_Msk) return; /* return if DCache is already enabled */ SCB->CSSELR = 0U; /* select Level 1 data cache */ __DSB(); ccsidr = SCB->CCSIDR; /* invalidate D-Cache */ sets = (uint32_t)(CCSIDR_SETS(ccsidr)); do { ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); do { SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); #if defined ( __CC_ARM ) __schedule_barrier(); #endif } while (ways-- != 0U); } while(sets-- != 0U); __DSB(); SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ __DSB(); __ISB(); #endif } /** \brief Disable D-Cache \details Turns off D-Cache */ __STATIC_FORCEINLINE void SCB_DisableDCache (void) { #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) uint32_t ccsidr; uint32_t sets; uint32_t ways; SCB->CSSELR = 0U; /* select Level 1 data cache */ __DSB(); SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */ __DSB(); ccsidr = SCB->CCSIDR; /* clean & invalidate D-Cache */ sets = (uint32_t)(CCSIDR_SETS(ccsidr)); do { ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); do { SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); #if defined ( __CC_ARM ) __schedule_barrier(); #endif } while (ways-- != 0U); } while(sets-- != 0U); __DSB(); __ISB(); #endif } /** \brief Invalidate D-Cache \details Invalidates D-Cache */ __STATIC_FORCEINLINE void SCB_InvalidateDCache (void) { #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) uint32_t ccsidr; uint32_t sets; uint32_t ways; SCB->CSSELR = 0U; /* select Level 1 data cache */ __DSB(); ccsidr = SCB->CCSIDR; /* invalidate D-Cache */ sets = (uint32_t)(CCSIDR_SETS(ccsidr)); do { ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); do { SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); #if defined ( __CC_ARM ) __schedule_barrier(); #endif } while (ways-- != 0U); } while(sets-- != 0U); __DSB(); __ISB(); #endif } /** \brief Clean D-Cache \details Cleans D-Cache */ __STATIC_FORCEINLINE void SCB_CleanDCache (void) { #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) uint32_t ccsidr; uint32_t sets; uint32_t ways; SCB->CSSELR = 0U; /* select Level 1 data cache */ __DSB(); ccsidr = SCB->CCSIDR; /* clean D-Cache */ sets = (uint32_t)(CCSIDR_SETS(ccsidr)); do { ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); do { SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) | ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) ); #if defined ( __CC_ARM ) __schedule_barrier(); #endif } while (ways-- != 0U); } while(sets-- != 0U); __DSB(); __ISB(); #endif } /** \brief Clean & Invalidate D-Cache \details Cleans and Invalidates D-Cache */ __STATIC_FORCEINLINE void SCB_CleanInvalidateDCache (void) { #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) uint32_t ccsidr; uint32_t sets; uint32_t ways; SCB->CSSELR = 0U; /* select Level 1 data cache */ __DSB(); ccsidr = SCB->CCSIDR; /* clean & invalidate D-Cache */ sets = (uint32_t)(CCSIDR_SETS(ccsidr)); do { ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); do { SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); #if defined ( __CC_ARM ) __schedule_barrier(); #endif } while (ways-- != 0U); } while(sets-- != 0U); __DSB(); __ISB(); #endif } /** \brief D-Cache Invalidate by address \details Invalidates D-Cache for the given address. D-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. D-Cache memory blocks which are part of given address + given size are invalidated. \param[in] addr address \param[in] dsize size of memory block (in number of bytes) */ __STATIC_FORCEINLINE void SCB_InvalidateDCache_by_Addr (void *addr, int32_t dsize) { #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) if ( dsize > 0 ) { int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; __DSB(); do { SCB->DCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ op_addr += __SCB_DCACHE_LINE_SIZE; op_size -= __SCB_DCACHE_LINE_SIZE; } while ( op_size > 0 ); __DSB(); __ISB(); } #endif } /** \brief D-Cache Clean by address \details Cleans D-Cache for the given address D-Cache is cleaned starting from a 32 byte aligned address in 32 byte granularity. D-Cache memory blocks which are part of given address + given size are cleaned. \param[in] addr address \param[in] dsize size of memory block (in number of bytes) */ __STATIC_FORCEINLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize) { #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) if ( dsize > 0 ) { int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; __DSB(); do { SCB->DCCMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ op_addr += __SCB_DCACHE_LINE_SIZE; op_size -= __SCB_DCACHE_LINE_SIZE; } while ( op_size > 0 ); __DSB(); __ISB(); } #endif } /** \brief D-Cache Clean and Invalidate by address \details Cleans and invalidates D_Cache for the given address D-Cache is cleaned and invalidated starting from a 32 byte aligned address in 32 byte granularity. D-Cache memory blocks which are part of given address + given size are cleaned and invalidated. \param[in] addr address (aligned to 32-byte boundary) \param[in] dsize size of memory block (in number of bytes) */ __STATIC_FORCEINLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) { #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) if ( dsize > 0 ) { int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; __DSB(); do { SCB->DCCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ op_addr += __SCB_DCACHE_LINE_SIZE; op_size -= __SCB_DCACHE_LINE_SIZE; } while ( op_size > 0 ); __DSB(); __ISB(); } #endif } /*@} end of CMSIS_Core_CacheFunctions */ /* ################################## SysTick function ############################################ */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SysTickFunctions SysTick Functions \brief Functions that configure the System. @{ */ #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #endif /*@} end of CMSIS_Core_SysTickFunctions */ /* ##################################### Debug In/Output function ########################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_core_DebugFunctions ITM Functions \brief Functions that access the ITM debug interface. @{ */ extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ #define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ /** \brief ITM Send Character \details Transmits a character via the ITM channel 0, and \li Just returns when no debugger is connected that has booked the output. \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. \param [in] ch Character to transmit. \returns Character to transmit. */ __STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) { if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ { while (ITM->PORT[0U].u32 == 0UL) { __NOP(); } ITM->PORT[0U].u8 = (uint8_t)ch; } return (ch); } /** \brief ITM Receive Character \details Inputs a character via the external variable \ref ITM_RxBuffer. \return Received character. \return -1 No character pending. */ __STATIC_INLINE int32_t ITM_ReceiveChar (void) { int32_t ch = -1; /* no character available */ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { ch = ITM_RxBuffer; ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ } return (ch); } /** \brief ITM Check Character \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. \return 0 No character available. \return 1 Character available. */ __STATIC_INLINE int32_t ITM_CheckChar (void) { if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { return (0); /* no character available */ } else { return (1); /* character available */ } } /*@} end of CMSIS_core_DebugFunctions */ #ifdef __cplusplus } #endif #endif /* __CORE_CM7_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ ================================================ FILE: 3rd_party/CMSIS/Include/core_sc000.h ================================================ /**************************************************************************//** * @file core_sc000.h * @brief CMSIS SC000 Core Peripheral Access Layer Header File * @version V5.0.6 * @date 12. November 2018 ******************************************************************************/ /* * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_SC000_H_GENERIC #define __CORE_SC000_H_GENERIC #include #ifdef __cplusplus extern "C" { #endif /** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions CMSIS violates the following MISRA-C:2004 rules: \li Required Rule 8.5, object/function definition in header file.
Function definitions in header files are used to allow 'inlining'. \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
Unions are used for effective representation of core registers. \li Advisory Rule 19.7, Function-like macro defined.
Function-like macros are used to allow more efficient code. */ /******************************************************************************* * CMSIS definitions ******************************************************************************/ /** \ingroup SC000 @{ */ #include "cmsis_version.h" /* CMSIS SC000 definitions */ #define __SC000_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ #define __SC000_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \ __SC000_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_SC (000U) /*!< Cortex secure core */ /** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all */ #define __FPU_USED 0U #if defined ( __CC_ARM ) #if defined __TARGET_FPU_VFP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined __ARM_FP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TASKING__ ) #if defined __FPU_VFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __CSMC__ ) #if ( __CSMC__ & 0x400U) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #endif #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ #ifdef __cplusplus } #endif #endif /* __CORE_SC000_H_GENERIC */ #ifndef __CMSIS_GENERIC #ifndef __CORE_SC000_H_DEPENDANT #define __CORE_SC000_H_DEPENDANT #ifdef __cplusplus extern "C" { #endif /* check device defines and use defaults */ #if defined __CHECK_DEVICE_DEFINES #ifndef __SC000_REV #define __SC000_REV 0x0000U #warning "__SC000_REV not defined in device header file; using default!" #endif #ifndef __MPU_PRESENT #define __MPU_PRESENT 0U #warning "__MPU_PRESENT not defined in device header file; using default!" #endif #ifndef __NVIC_PRIO_BITS #define __NVIC_PRIO_BITS 2U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif #ifndef __Vendor_SysTickConfig #define __Vendor_SysTickConfig 0U #warning "__Vendor_SysTickConfig not defined in device header file; using default!" #endif #endif /* IO definitions (access restrictions to peripheral registers) */ /** \defgroup CMSIS_glob_defs CMSIS Global Defines IO Type Qualifiers are used \li to specify the access to peripheral variables. \li for automatic generation of peripheral register debug information. */ #ifdef __cplusplus #define __I volatile /*!< Defines 'read only' permissions */ #else #define __I volatile const /*!< Defines 'read only' permissions */ #endif #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */ /* following defines should be used for structure members */ #define __IM volatile const /*! Defines 'read only' structure member permissions */ #define __OM volatile /*! Defines 'write only' structure member permissions */ #define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group SC000 */ /******************************************************************************* * Register Abstraction Core Register contain: - Core Register - Core NVIC Register - Core SCB Register - Core SysTick Register - Core MPU Register ******************************************************************************/ /** \defgroup CMSIS_core_register Defines and Type Definitions \brief Type definitions and defines for Cortex-M processor based devices. */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CORE Status and Control Registers \brief Core Register type definitions. @{ */ /** \brief Union type to access the Application Program Status Register (APSR). */ typedef union { struct { uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } APSR_Type; /* APSR Register Definitions */ #define APSR_N_Pos 31U /*!< APSR: N Position */ #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ #define APSR_Z_Pos 30U /*!< APSR: Z Position */ #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ #define APSR_C_Pos 29U /*!< APSR: C Position */ #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ #define APSR_V_Pos 28U /*!< APSR: V Position */ #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ /** \brief Union type to access the Interrupt Program Status Register (IPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } IPSR_Type; /* IPSR Register Definitions */ #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ /** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } xPSR_Type; /* xPSR Register Definitions */ #define xPSR_N_Pos 31U /*!< xPSR: N Position */ #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ #define xPSR_C_Pos 29U /*!< xPSR: C Position */ #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ #define xPSR_V_Pos 28U /*!< xPSR: V Position */ #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ /** \brief Union type to access the Control Registers (CONTROL). */ typedef union { struct { uint32_t _reserved0:1; /*!< bit: 0 Reserved */ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } CONTROL_Type; /* CONTROL Register Definitions */ #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ /*@} end of group CMSIS_CORE */ /** \ingroup CMSIS_core_register \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) \brief Type definitions for the NVIC Registers @{ */ /** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). */ typedef struct { __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[31U]; __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ uint32_t RSERVED1[31U]; __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[31U]; __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ uint32_t RESERVED3[31U]; uint32_t RESERVED4[64U]; __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ } NVIC_Type; /*@} end of group CMSIS_NVIC */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCB System Control Block (SCB) \brief Type definitions for the System Control Block Registers @{ */ /** \brief Structure type to access the System Control Block (SCB). */ typedef struct { __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ uint32_t RESERVED0[1U]; __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ uint32_t RESERVED1[154U]; __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ } SCB_Type; /* SCB CPUID Register Definitions */ #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ /* SCB Interrupt Control State Register Definitions */ #define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ #define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ /* SCB Interrupt Control State Register Definitions */ #define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ #define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ /* SCB Application Interrupt and Reset Control Register Definitions */ #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ /* SCB System Control Register Definitions */ #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ /* SCB Configuration Control Register Definitions */ #define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ #define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ /* SCB System Handler Control and State Register Definitions */ #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ /*@} end of group CMSIS_SCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) \brief Type definitions for the System Control and ID Register not in the SCB @{ */ /** \brief Structure type to access the System Control and ID Register not in the SCB. */ typedef struct { uint32_t RESERVED0[2U]; __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ } SCnSCB_Type; /* Auxiliary Control Register Definitions */ #define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ #define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ /*@} end of group CMSIS_SCnotSCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SysTick System Tick Timer (SysTick) \brief Type definitions for the System Timer Registers. @{ */ /** \brief Structure type to access the System Timer (SysTick). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; /* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ /* SysTick Calibration Register Definitions */ #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ /*@} end of group CMSIS_SysTick */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) /** \ingroup CMSIS_core_register \defgroup CMSIS_MPU Memory Protection Unit (MPU) \brief Type definitions for the Memory Protection Unit (MPU) @{ */ /** \brief Structure type to access the Memory Protection Unit (MPU). */ typedef struct { __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ } MPU_Type; /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ #define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ #define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ #define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ #define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ /* MPU Control Register Definitions */ #define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ #define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ #define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ #define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ #define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ #define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ /* MPU Region Number Register Definitions */ #define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ #define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ /* MPU Region Base Address Register Definitions */ #define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ #define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ #define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ #define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ #define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ #define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ /* MPU Region Attribute and Size Register Definitions */ #define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ #define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ #define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ #define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ #define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ #define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ #define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ #define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ #define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ #define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ #define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ #define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ #define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ #define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ #define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ #define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ #define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ #define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ #define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ #define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ /*@} end of group CMSIS_MPU */ #endif /** \ingroup CMSIS_core_register \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) \brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. Therefore they are not covered by the SC000 header file. @{ */ /*@} end of group CMSIS_CoreDebug */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_bitfield Core register bit field macros \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). @{ */ /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_base Core Definitions \brief Definitions for base addresses, unions, and structures. @{ */ /* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ #endif /*@} */ /******************************************************************************* * Hardware Abstraction Layer Core Function Interface contains: - Core NVIC Functions - Core SysTick Functions - Core Register Access Functions ******************************************************************************/ /** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference */ /* ########################## NVIC functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_NVICFunctions NVIC Functions \brief Functions that manage interrupts and exceptions via the NVIC. @{ */ #ifdef CMSIS_NVIC_VIRTUAL #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" #endif #include CMSIS_NVIC_VIRTUAL_HEADER_FILE #else /*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for SC000 */ /*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for SC000 */ #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ /*#define NVIC_GetActive __NVIC_GetActive not available for SC000 */ #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ #ifdef CMSIS_VECTAB_VIRTUAL #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" #endif #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE #else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ #define NVIC_USER_IRQ_OFFSET 16 /* The following EXC_RETURN values are saved the LR on exception entry */ #define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ #define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ #define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ /* Interrupt Priorities are WORD accessible only under Armv6-M */ /* The following MACROS handle generation of the register offset and byte masks */ #define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) #define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) #define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) /** \brief Enable Interrupt \details Enables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { __COMPILER_BARRIER(); NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __COMPILER_BARRIER(); } } /** \brief Get Interrupt Enable status \details Returns a device specific interrupt enable status from the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt \details Disables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } } /** \brief Get Pending Interrupt \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt \details Sets the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt \details Clears the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Set Interrupt Priority \details Sets the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every processor exception. */ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } else { SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } } /** \brief Get Interrupt Priority \details Reads the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } else { return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } } /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. VTOR must been relocated to SRAM before. \param [in] IRQn Interrupt number \param [in] vector Address of interrupt handler function */ __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { uint32_t *vectors = (uint32_t *)SCB->VTOR; vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; /* ARM Application Note 321 states that the M0 and M0+ do not require the architectural barrier - assume SC000 is the same */ } /** \brief Get Interrupt Vector \details Reads an interrupt vector from interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Address of interrupt handler function */ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) { uint32_t *vectors = (uint32_t *)SCB->VTOR; return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; } /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk); __DSB(); /* Ensure completion of memory access */ for(;;) /* wait until reset */ { __NOP(); } } /*@} end of CMSIS_Core_NVICFunctions */ /* ########################## FPU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_FpuFunctions FPU Functions \brief Function that provides FPU type. @{ */ /** \brief get FPU type \details returns the FPU type \returns - \b 0: No FPU - \b 1: Single precision FPU - \b 2: Double + Single precision FPU */ __STATIC_INLINE uint32_t SCB_GetFPUType(void) { return 0U; /* No FPU */ } /*@} end of CMSIS_Core_FpuFunctions */ /* ################################## SysTick function ############################################ */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SysTickFunctions SysTick Functions \brief Functions that configure the System. @{ */ #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #endif /*@} end of CMSIS_Core_SysTickFunctions */ #ifdef __cplusplus } #endif #endif /* __CORE_SC000_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ ================================================ FILE: 3rd_party/CMSIS/Include/core_sc300.h ================================================ /**************************************************************************//** * @file core_sc300.h * @brief CMSIS SC300 Core Peripheral Access Layer Header File * @version V5.0.8 * @date 31. May 2019 ******************************************************************************/ /* * Copyright (c) 2009-2019 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_SC300_H_GENERIC #define __CORE_SC300_H_GENERIC #include #ifdef __cplusplus extern "C" { #endif /** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions CMSIS violates the following MISRA-C:2004 rules: \li Required Rule 8.5, object/function definition in header file.
Function definitions in header files are used to allow 'inlining'. \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
Unions are used for effective representation of core registers. \li Advisory Rule 19.7, Function-like macro defined.
Function-like macros are used to allow more efficient code. */ /******************************************************************************* * CMSIS definitions ******************************************************************************/ /** \ingroup SC3000 @{ */ #include "cmsis_version.h" /* CMSIS SC300 definitions */ #define __SC300_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ #define __SC300_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __SC300_CMSIS_VERSION ((__SC300_CMSIS_VERSION_MAIN << 16U) | \ __SC300_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_SC (300U) /*!< Cortex secure core */ /** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all */ #define __FPU_USED 0U #if defined ( __CC_ARM ) #if defined __TARGET_FPU_VFP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined __ARM_FP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TASKING__ ) #if defined __FPU_VFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __CSMC__ ) #if ( __CSMC__ & 0x400U) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #endif #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ #ifdef __cplusplus } #endif #endif /* __CORE_SC300_H_GENERIC */ #ifndef __CMSIS_GENERIC #ifndef __CORE_SC300_H_DEPENDANT #define __CORE_SC300_H_DEPENDANT #ifdef __cplusplus extern "C" { #endif /* check device defines and use defaults */ #if defined __CHECK_DEVICE_DEFINES #ifndef __SC300_REV #define __SC300_REV 0x0000U #warning "__SC300_REV not defined in device header file; using default!" #endif #ifndef __MPU_PRESENT #define __MPU_PRESENT 0U #warning "__MPU_PRESENT not defined in device header file; using default!" #endif #ifndef __NVIC_PRIO_BITS #define __NVIC_PRIO_BITS 3U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif #ifndef __Vendor_SysTickConfig #define __Vendor_SysTickConfig 0U #warning "__Vendor_SysTickConfig not defined in device header file; using default!" #endif #endif /* IO definitions (access restrictions to peripheral registers) */ /** \defgroup CMSIS_glob_defs CMSIS Global Defines IO Type Qualifiers are used \li to specify the access to peripheral variables. \li for automatic generation of peripheral register debug information. */ #ifdef __cplusplus #define __I volatile /*!< Defines 'read only' permissions */ #else #define __I volatile const /*!< Defines 'read only' permissions */ #endif #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */ /* following defines should be used for structure members */ #define __IM volatile const /*! Defines 'read only' structure member permissions */ #define __OM volatile /*! Defines 'write only' structure member permissions */ #define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group SC300 */ /******************************************************************************* * Register Abstraction Core Register contain: - Core Register - Core NVIC Register - Core SCB Register - Core SysTick Register - Core Debug Register - Core MPU Register ******************************************************************************/ /** \defgroup CMSIS_core_register Defines and Type Definitions \brief Type definitions and defines for Cortex-M processor based devices. */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CORE Status and Control Registers \brief Core Register type definitions. @{ */ /** \brief Union type to access the Application Program Status Register (APSR). */ typedef union { struct { uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } APSR_Type; /* APSR Register Definitions */ #define APSR_N_Pos 31U /*!< APSR: N Position */ #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ #define APSR_Z_Pos 30U /*!< APSR: Z Position */ #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ #define APSR_C_Pos 29U /*!< APSR: C Position */ #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ #define APSR_V_Pos 28U /*!< APSR: V Position */ #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ #define APSR_Q_Pos 27U /*!< APSR: Q Position */ #define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ /** \brief Union type to access the Interrupt Program Status Register (IPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } IPSR_Type; /* IPSR Register Definitions */ #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ /** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:1; /*!< bit: 9 Reserved */ uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */ uint32_t T:1; /*!< bit: 24 Thumb bit */ uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } xPSR_Type; /* xPSR Register Definitions */ #define xPSR_N_Pos 31U /*!< xPSR: N Position */ #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ #define xPSR_C_Pos 29U /*!< xPSR: C Position */ #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ #define xPSR_V_Pos 28U /*!< xPSR: V Position */ #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ #define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ #define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ #define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ #define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ #define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ #define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ /** \brief Union type to access the Control Registers (CONTROL). */ typedef union { struct { uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } CONTROL_Type; /* CONTROL Register Definitions */ #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ #define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ #define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ /*@} end of group CMSIS_CORE */ /** \ingroup CMSIS_core_register \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) \brief Type definitions for the NVIC Registers @{ */ /** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). */ typedef struct { __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[24U]; __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ uint32_t RESERVED1[24U]; __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[24U]; __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ uint32_t RESERVED3[24U]; __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ uint32_t RESERVED4[56U]; __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ uint32_t RESERVED5[644U]; __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ } NVIC_Type; /* Software Triggered Interrupt Register Definitions */ #define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ #define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ /*@} end of group CMSIS_NVIC */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCB System Control Block (SCB) \brief Type definitions for the System Control Block Registers @{ */ /** \brief Structure type to access the System Control Block (SCB). */ typedef struct { __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ uint32_t RESERVED0[5U]; __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ uint32_t RESERVED1[129U]; __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ } SCB_Type; /* SCB CPUID Register Definitions */ #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ /* SCB Interrupt Control State Register Definitions */ #define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ #define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ #define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ #define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ /* SCB Vector Table Offset Register Definitions */ #define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ #define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ #define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ #define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ /* SCB Application Interrupt and Reset Control Register Definitions */ #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ #define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ #define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ #define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ #define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ /* SCB System Control Register Definitions */ #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ /* SCB Configuration Control Register Definitions */ #define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ #define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ #define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ #define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ #define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ #define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ #define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ #define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ #define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ #define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ /* SCB System Handler Control and State Register Definitions */ #define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ #define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ #define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ #define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ #define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ #define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ #define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ #define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ #define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ #define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ #define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ #define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ #define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ #define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ #define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ #define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ #define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ #define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ #define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ #define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ #define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ #define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ #define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ #define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ #define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ #define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ /* SCB Configurable Fault Status Register Definitions */ #define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ #define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ #define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ #define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ #define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ #define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ /* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ #define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ #define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ #define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ #define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ #define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ #define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ #define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ #define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ #define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ /* BusFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ #define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ #define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ #define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ #define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ #define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ #define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ #define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ #define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ #define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ #define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ #define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ /* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ #define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ #define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ #define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ #define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ #define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ #define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ #define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ #define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ #define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ #define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ #define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ /* SCB Hard Fault Status Register Definitions */ #define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ #define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ #define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ #define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ #define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ #define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ /* SCB Debug Fault Status Register Definitions */ #define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ #define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ #define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ #define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ #define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ #define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ #define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ #define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ #define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ #define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ /*@} end of group CMSIS_SCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) \brief Type definitions for the System Control and ID Register not in the SCB @{ */ /** \brief Structure type to access the System Control and ID Register not in the SCB. */ typedef struct { uint32_t RESERVED0[1U]; __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ } SCnSCB_Type; /* Interrupt Controller Type Register Definitions */ #define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ #define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ /* Auxiliary Control Register Definitions */ #define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ #define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ #define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ #define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ #define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ #define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ /*@} end of group CMSIS_SCnotSCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SysTick System Tick Timer (SysTick) \brief Type definitions for the System Timer Registers. @{ */ /** \brief Structure type to access the System Timer (SysTick). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; /* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ /* SysTick Calibration Register Definitions */ #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ /*@} end of group CMSIS_SysTick */ /** \ingroup CMSIS_core_register \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) \brief Type definitions for the Instrumentation Trace Macrocell (ITM) @{ */ /** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). */ typedef struct { __OM union { __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ uint32_t RESERVED0[864U]; __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ uint32_t RESERVED1[15U]; __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ uint32_t RESERVED2[15U]; __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ uint32_t RESERVED3[32U]; uint32_t RESERVED4[43U]; __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ uint32_t RESERVED5[6U]; __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ } ITM_Type; /* ITM Trace Privilege Register Definitions */ #define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ #define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ /* ITM Trace Control Register Definitions */ #define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ #define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ #define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ #define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ #define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ #define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ #define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ #define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ #define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ #define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ #define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ #define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ #define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ #define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ #define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ #define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ #define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ #define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ /* ITM Lock Status Register Definitions */ #define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ #define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ #define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ #define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ #define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ #define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ /*@}*/ /* end of group CMSIS_ITM */ /** \ingroup CMSIS_core_register \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) \brief Type definitions for the Data Watchpoint and Trace (DWT) @{ */ /** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ uint32_t RESERVED0[1U]; __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ uint32_t RESERVED1[1U]; __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ uint32_t RESERVED2[1U]; __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ } DWT_Type; /* DWT Control Register Definitions */ #define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ #define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ #define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ #define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ #define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ #define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ #define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ #define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ #define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ #define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ #define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ #define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ #define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ #define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ #define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ #define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ #define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ #define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ #define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ #define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ #define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ #define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ #define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ #define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ #define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ #define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ #define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ #define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ #define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ #define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ #define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ #define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ #define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ #define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ #define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ #define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ /* DWT CPI Count Register Definitions */ #define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ #define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ /* DWT Exception Overhead Count Register Definitions */ #define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ #define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ /* DWT Sleep Count Register Definitions */ #define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ #define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ /* DWT LSU Count Register Definitions */ #define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ #define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ /* DWT Folded-instruction Count Register Definitions */ #define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ #define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ /* DWT Comparator Mask Register Definitions */ #define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ #define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ /* DWT Comparator Function Register Definitions */ #define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ #define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ #define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ #define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ #define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ #define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ #define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ #define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ #define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ #define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ #define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ #define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ #define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ #define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ #define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ #define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ #define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ #define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ /*@}*/ /* end of group CMSIS_DWT */ /** \ingroup CMSIS_core_register \defgroup CMSIS_TPI Trace Port Interface (TPI) \brief Type definitions for the Trace Port Interface (TPI) @{ */ /** \brief Structure type to access the Trace Port Interface Register (TPI). */ typedef struct { __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ uint32_t RESERVED1[55U]; __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ uint32_t RESERVED2[131U]; __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ uint32_t RESERVED3[759U]; __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ uint32_t RESERVED4[1U]; __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ uint32_t RESERVED5[39U]; __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ uint32_t RESERVED7[8U]; __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ } TPI_Type; /* TPI Asynchronous Clock Prescaler Register Definitions */ #define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ #define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ /* TPI Selected Pin Protocol Register Definitions */ #define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ #define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ /* TPI Formatter and Flush Status Register Definitions */ #define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ #define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ #define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ #define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ #define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ #define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ #define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ #define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ /* TPI Formatter and Flush Control Register Definitions */ #define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ #define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ #define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ #define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ /* TPI TRIGGER Register Definitions */ #define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ #define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ /* TPI Integration ETM Data Register Definitions (FIFO0) */ #define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ #define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ #define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ #define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ #define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ #define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ #define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ #define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ #define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ #define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ #define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ #define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ #define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ #define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ /* TPI ITATBCTR2 Register Definitions */ #define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ #define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ #define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ #define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ /* TPI Integration ITM Data Register Definitions (FIFO1) */ #define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ #define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ #define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ #define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ #define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ #define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ #define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ #define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ #define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ #define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ #define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ #define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ #define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ #define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ /* TPI ITATBCTR0 Register Definitions */ #define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ #define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ #define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ #define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ /* TPI Integration Mode Control Register Definitions */ #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ #define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ #define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ #define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ #define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ #define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ #define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ #define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ #define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ #define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ #define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ #define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ #define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ #define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ #define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ #define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ /*@}*/ /* end of group CMSIS_TPI */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) /** \ingroup CMSIS_core_register \defgroup CMSIS_MPU Memory Protection Unit (MPU) \brief Type definitions for the Memory Protection Unit (MPU) @{ */ /** \brief Structure type to access the Memory Protection Unit (MPU). */ typedef struct { __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ } MPU_Type; /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ #define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ #define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ #define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ #define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ /* MPU Control Register Definitions */ #define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ #define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ #define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ #define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ #define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ #define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ /* MPU Region Number Register Definitions */ #define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ #define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ /* MPU Region Base Address Register Definitions */ #define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ #define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ #define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ #define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ #define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ #define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ /* MPU Region Attribute and Size Register Definitions */ #define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ #define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ #define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ #define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ #define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ #define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ #define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ #define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ #define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ #define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ #define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ #define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ #define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ #define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ #define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ #define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ #define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ #define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ #define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ #define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ /*@} end of group CMSIS_MPU */ #endif /** \ingroup CMSIS_core_register \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) \brief Type definitions for the Core Debug Registers @{ */ /** \brief Structure type to access the Core Debug Register (CoreDebug). */ typedef struct { __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ } CoreDebug_Type; /* Debug Halting Control and Status Register Definitions */ #define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ #define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ #define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ #define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ #define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ #define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ #define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ #define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ #define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ #define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ #define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ #define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ #define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ #define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ #define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ #define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ #define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ #define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ #define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ #define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ #define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ #define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ /* Debug Core Register Selector Register Definitions */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ #define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ /* Debug Exception and Monitor Control Register Definitions */ #define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ #define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ #define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ #define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ #define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ #define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ #define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ #define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ #define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ #define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ #define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ #define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ #define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ #define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ #define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ #define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ #define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ #define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ #define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ #define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ #define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ #define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ #define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ #define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ #define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ #define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ /*@} end of group CMSIS_CoreDebug */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_bitfield Core register bit field macros \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). @{ */ /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_base Core Definitions \brief Definitions for base addresses, unions, and structures. @{ */ /* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ #endif /*@} */ /******************************************************************************* * Hardware Abstraction Layer Core Function Interface contains: - Core NVIC Functions - Core SysTick Functions - Core Debug Functions - Core Register Access Functions ******************************************************************************/ /** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference */ /* ########################## NVIC functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_NVICFunctions NVIC Functions \brief Functions that manage interrupts and exceptions via the NVIC. @{ */ #ifdef CMSIS_NVIC_VIRTUAL #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" #endif #include CMSIS_NVIC_VIRTUAL_HEADER_FILE #else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ #define NVIC_GetActive __NVIC_GetActive #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ #ifdef CMSIS_VECTAB_VIRTUAL #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" #endif #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE #else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ #define NVIC_USER_IRQ_OFFSET 16 /* The following EXC_RETURN values are saved the LR on exception entry */ #define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ #define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ #define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ /** \brief Set Priority Grouping \details Sets the priority grouping field using the required unlock sequence. The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Priority grouping field. */ __STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ reg_value = SCB->AIRCR; /* read old register configuration */ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB->AIRCR = reg_value; } /** \brief Get Priority Grouping \details Reads the priority grouping field from the NVIC Interrupt Controller. \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ __STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) { return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); } /** \brief Enable Interrupt \details Enables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { __COMPILER_BARRIER(); NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __COMPILER_BARRIER(); } } /** \brief Get Interrupt Enable status \details Returns a device specific interrupt enable status from the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt \details Disables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } } /** \brief Get Pending Interrupt \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt \details Sets the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt \details Clears the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Priority \details Sets the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every processor exception. */ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } /** \brief Get Interrupt Priority \details Reads the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } /** \brief Encode Priority \details Encodes the priority for an interrupt with the given priority group, preemptive priority value, and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Used priority group. \param [in] PreemptPriority Preemptive priority value (starting from 0). \param [in] SubPriority Subpriority value (starting from 0). \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). */ __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); return ( ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) ); } /** \brief Decode Priority \details Decodes an interrupt priority value with a given priority group to preemptive priority value and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). \param [in] PriorityGroup Used priority group. \param [out] pPreemptPriority Preemptive priority value (starting from 0). \param [out] pSubPriority Subpriority value (starting from 0). */ __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); } /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. VTOR must been relocated to SRAM before. \param [in] IRQn Interrupt number \param [in] vector Address of interrupt handler function */ __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { uint32_t vectors = (uint32_t )SCB->VTOR; (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; /* ARM Application Note 321 states that the M3 does not require the architectural barrier */ } /** \brief Get Interrupt Vector \details Reads an interrupt vector from interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Address of interrupt handler function */ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) { uint32_t vectors = (uint32_t )SCB->VTOR; return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); } /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ __DSB(); /* Ensure completion of memory access */ for(;;) /* wait until reset */ { __NOP(); } } /*@} end of CMSIS_Core_NVICFunctions */ /* ########################## FPU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_FpuFunctions FPU Functions \brief Function that provides FPU type. @{ */ /** \brief get FPU type \details returns the FPU type \returns - \b 0: No FPU - \b 1: Single precision FPU - \b 2: Double + Single precision FPU */ __STATIC_INLINE uint32_t SCB_GetFPUType(void) { return 0U; /* No FPU */ } /*@} end of CMSIS_Core_FpuFunctions */ /* ################################## SysTick function ############################################ */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SysTickFunctions SysTick Functions \brief Functions that configure the System. @{ */ #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #endif /*@} end of CMSIS_Core_SysTickFunctions */ /* ##################################### Debug In/Output function ########################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_core_DebugFunctions ITM Functions \brief Functions that access the ITM debug interface. @{ */ extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ #define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ /** \brief ITM Send Character \details Transmits a character via the ITM channel 0, and \li Just returns when no debugger is connected that has booked the output. \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. \param [in] ch Character to transmit. \returns Character to transmit. */ __STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) { if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ { while (ITM->PORT[0U].u32 == 0UL) { __NOP(); } ITM->PORT[0U].u8 = (uint8_t)ch; } return (ch); } /** \brief ITM Receive Character \details Inputs a character via the external variable \ref ITM_RxBuffer. \return Received character. \return -1 No character pending. */ __STATIC_INLINE int32_t ITM_ReceiveChar (void) { int32_t ch = -1; /* no character available */ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { ch = ITM_RxBuffer; ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ } return (ch); } /** \brief ITM Check Character \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. \return 0 No character available. \return 1 Character available. */ __STATIC_INLINE int32_t ITM_CheckChar (void) { if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { return (0); /* no character available */ } else { return (1); /* character available */ } } /*@} end of CMSIS_core_DebugFunctions */ #ifdef __cplusplus } #endif #endif /* __CORE_SC300_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ ================================================ FILE: 3rd_party/CMSIS/Include/mpu_armv7.h ================================================ /****************************************************************************** * @file mpu_armv7.h * @brief CMSIS MPU API for Armv7-M MPU * @version V5.1.0 * @date 08. March 2019 ******************************************************************************/ /* * Copyright (c) 2017-2019 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef ARM_MPU_ARMV7_H #define ARM_MPU_ARMV7_H #define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes #define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes #define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes #define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes #define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes #define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte #define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes #define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes #define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes #define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes #define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes #define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes #define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes #define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes #define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes #define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte #define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes #define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes #define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes #define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes #define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes #define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes #define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes #define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes #define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes #define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte #define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes #define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes #define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access #define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only #define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only #define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access #define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only #define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access /** MPU Region Base Address Register Value * * \param Region The region to be configured, number 0 to 15. * \param BaseAddress The base address for the region. */ #define ARM_MPU_RBAR(Region, BaseAddress) \ (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ ((Region) & MPU_RBAR_REGION_Msk) | \ (MPU_RBAR_VALID_Msk)) /** * MPU Memory Access Attributes * * \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. * \param IsShareable Region is shareable between multiple bus masters. * \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. * \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. */ #define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ ((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ (((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ (((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ (((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) /** * MPU Region Attribute and Size Register Value * * \param DisableExec Instruction access disable bit, 1= disable instruction fetches. * \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. * \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. * \param SubRegionDisable Sub-region disable field. * \param Size Region size of the region to be configured, for example 4K, 8K. */ #define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ ((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ (((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \ (((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \ (((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \ (((MPU_RASR_ENABLE_Msk)))) /** * MPU Region Attribute and Size Register Value * * \param DisableExec Instruction access disable bit, 1= disable instruction fetches. * \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. * \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. * \param IsShareable Region is shareable between multiple bus masters. * \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. * \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. * \param SubRegionDisable Sub-region disable field. * \param Size Region size of the region to be configured, for example 4K, 8K. */ #define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) /** * MPU Memory Access Attribute for strongly ordered memory. * - TEX: 000b * - Shareable * - Non-cacheable * - Non-bufferable */ #define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) /** * MPU Memory Access Attribute for device memory. * - TEX: 000b (if shareable) or 010b (if non-shareable) * - Shareable or non-shareable * - Non-cacheable * - Bufferable (if shareable) or non-bufferable (if non-shareable) * * \param IsShareable Configures the device memory as shareable or non-shareable. */ #define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) /** * MPU Memory Access Attribute for normal memory. * - TEX: 1BBb (reflecting outer cacheability rules) * - Shareable or non-shareable * - Cacheable or non-cacheable (reflecting inner cacheability rules) * - Bufferable or non-bufferable (reflecting inner cacheability rules) * * \param OuterCp Configures the outer cache policy. * \param InnerCp Configures the inner cache policy. * \param IsShareable Configures the memory as shareable or non-shareable. */ #define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) & 2U), ((InnerCp) & 1U)) /** * MPU Memory Access Attribute non-cacheable policy. */ #define ARM_MPU_CACHEP_NOCACHE 0U /** * MPU Memory Access Attribute write-back, write and read allocate policy. */ #define ARM_MPU_CACHEP_WB_WRA 1U /** * MPU Memory Access Attribute write-through, no write allocate policy. */ #define ARM_MPU_CACHEP_WT_NWA 2U /** * MPU Memory Access Attribute write-back, no write allocate policy. */ #define ARM_MPU_CACHEP_WB_NWA 3U /** * Struct for a single MPU Region */ typedef struct { uint32_t RBAR; //!< The region base address register value (RBAR) uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR } ARM_MPU_Region_t; /** Enable the MPU. * \param MPU_Control Default access permissions for unconfigured regions. */ __STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) { MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; #ifdef SCB_SHCSR_MEMFAULTENA_Msk SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; #endif __DSB(); __ISB(); } /** Disable the MPU. */ __STATIC_INLINE void ARM_MPU_Disable(void) { __DMB(); #ifdef SCB_SHCSR_MEMFAULTENA_Msk SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; #endif MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; } /** Clear and disable the given MPU region. * \param rnr Region number to be cleared. */ __STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) { MPU->RNR = rnr; MPU->RASR = 0U; } /** Configure an MPU region. * \param rbar Value for RBAR register. * \param rsar Value for RSAR register. */ __STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) { MPU->RBAR = rbar; MPU->RASR = rasr; } /** Configure the given MPU region. * \param rnr Region number to be configured. * \param rbar Value for RBAR register. * \param rsar Value for RSAR register. */ __STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) { MPU->RNR = rnr; MPU->RBAR = rbar; MPU->RASR = rasr; } /** Memcopy with strictly ordered memory access, e.g. for register targets. * \param dst Destination data is copied to. * \param src Source data is copied from. * \param len Amount of data words to be copied. */ __STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) { uint32_t i; for (i = 0U; i < len; ++i) { dst[i] = src[i]; } } /** Load the given number of MPU regions from a table. * \param table Pointer to the MPU configuration table. * \param cnt Amount of regions to be configured. */ __STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) { const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; while (cnt > MPU_TYPE_RALIASES) { ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); table += MPU_TYPE_RALIASES; cnt -= MPU_TYPE_RALIASES; } ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); } #endif ================================================ FILE: 3rd_party/CMSIS/Include/mpu_armv8.h ================================================ /****************************************************************************** * @file mpu_armv8.h * @brief CMSIS MPU API for Armv8-M and Armv8.1-M MPU * @version V5.1.0 * @date 08. March 2019 ******************************************************************************/ /* * Copyright (c) 2017-2019 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef ARM_MPU_ARMV8_H #define ARM_MPU_ARMV8_H /** \brief Attribute for device memory (outer only) */ #define ARM_MPU_ATTR_DEVICE ( 0U ) /** \brief Attribute for non-cacheable, normal memory */ #define ARM_MPU_ATTR_NON_CACHEABLE ( 4U ) /** \brief Attribute for normal memory (outer and inner) * \param NT Non-Transient: Set to 1 for non-transient data. * \param WB Write-Back: Set to 1 to use write-back update policy. * \param RA Read Allocation: Set to 1 to use cache allocation on read miss. * \param WA Write Allocation: Set to 1 to use cache allocation on write miss. */ #define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \ (((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U)) /** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */ #define ARM_MPU_ATTR_DEVICE_nGnRnE (0U) /** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */ #define ARM_MPU_ATTR_DEVICE_nGnRE (1U) /** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */ #define ARM_MPU_ATTR_DEVICE_nGRE (2U) /** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */ #define ARM_MPU_ATTR_DEVICE_GRE (3U) /** \brief Memory Attribute * \param O Outer memory attributes * \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes */ #define ARM_MPU_ATTR(O, I) (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U))) /** \brief Normal memory non-shareable */ #define ARM_MPU_SH_NON (0U) /** \brief Normal memory outer shareable */ #define ARM_MPU_SH_OUTER (2U) /** \brief Normal memory inner shareable */ #define ARM_MPU_SH_INNER (3U) /** \brief Memory access permissions * \param RO Read-Only: Set to 1 for read-only memory. * \param NP Non-Privileged: Set to 1 for non-privileged memory. */ #define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U)) /** \brief Region Base Address Register value * \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned. * \param SH Defines the Shareability domain for this memory region. * \param RO Read-Only: Set to 1 for a read-only memory region. * \param NP Non-Privileged: Set to 1 for a non-privileged memory region. * \oaram XN eXecute Never: Set to 1 for a non-executable memory region. */ #define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \ ((BASE & MPU_RBAR_BASE_Msk) | \ ((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \ ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \ ((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk)) /** \brief Region Limit Address Register value * \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. * \param IDX The attribute index to be associated with this memory region. */ #define ARM_MPU_RLAR(LIMIT, IDX) \ ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ (MPU_RLAR_EN_Msk)) #if defined(MPU_RLAR_PXN_Pos) /** \brief Region Limit Address Register with PXN value * \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. * \param PXN Privileged execute never. Defines whether code can be executed from this privileged region. * \param IDX The attribute index to be associated with this memory region. */ #define ARM_MPU_RLAR_PXN(LIMIT, PXN, IDX) \ ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ ((PXN << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk) | \ ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ (MPU_RLAR_EN_Msk)) #endif /** * Struct for a single MPU Region */ typedef struct { uint32_t RBAR; /*!< Region Base Address Register value */ uint32_t RLAR; /*!< Region Limit Address Register value */ } ARM_MPU_Region_t; /** Enable the MPU. * \param MPU_Control Default access permissions for unconfigured regions. */ __STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) { MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; #ifdef SCB_SHCSR_MEMFAULTENA_Msk SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; #endif __DSB(); __ISB(); } /** Disable the MPU. */ __STATIC_INLINE void ARM_MPU_Disable(void) { __DMB(); #ifdef SCB_SHCSR_MEMFAULTENA_Msk SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; #endif MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; } #ifdef MPU_NS /** Enable the Non-secure MPU. * \param MPU_Control Default access permissions for unconfigured regions. */ __STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control) { MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; #ifdef SCB_SHCSR_MEMFAULTENA_Msk SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; #endif __DSB(); __ISB(); } /** Disable the Non-secure MPU. */ __STATIC_INLINE void ARM_MPU_Disable_NS(void) { __DMB(); #ifdef SCB_SHCSR_MEMFAULTENA_Msk SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; #endif MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk; } #endif /** Set the memory attribute encoding to the given MPU. * \param mpu Pointer to the MPU to be configured. * \param idx The attribute index to be set [0-7] * \param attr The attribute value to be set. */ __STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr) { const uint8_t reg = idx / 4U; const uint32_t pos = ((idx % 4U) * 8U); const uint32_t mask = 0xFFU << pos; if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) { return; // invalid index } mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask)); } /** Set the memory attribute encoding. * \param idx The attribute index to be set [0-7] * \param attr The attribute value to be set. */ __STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr) { ARM_MPU_SetMemAttrEx(MPU, idx, attr); } #ifdef MPU_NS /** Set the memory attribute encoding to the Non-secure MPU. * \param idx The attribute index to be set [0-7] * \param attr The attribute value to be set. */ __STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr) { ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr); } #endif /** Clear and disable the given MPU region of the given MPU. * \param mpu Pointer to MPU to be used. * \param rnr Region number to be cleared. */ __STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr) { mpu->RNR = rnr; mpu->RLAR = 0U; } /** Clear and disable the given MPU region. * \param rnr Region number to be cleared. */ __STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) { ARM_MPU_ClrRegionEx(MPU, rnr); } #ifdef MPU_NS /** Clear and disable the given Non-secure MPU region. * \param rnr Region number to be cleared. */ __STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr) { ARM_MPU_ClrRegionEx(MPU_NS, rnr); } #endif /** Configure the given MPU region of the given MPU. * \param mpu Pointer to MPU to be used. * \param rnr Region number to be configured. * \param rbar Value for RBAR register. * \param rlar Value for RLAR register. */ __STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar) { mpu->RNR = rnr; mpu->RBAR = rbar; mpu->RLAR = rlar; } /** Configure the given MPU region. * \param rnr Region number to be configured. * \param rbar Value for RBAR register. * \param rlar Value for RLAR register. */ __STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar) { ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar); } #ifdef MPU_NS /** Configure the given Non-secure MPU region. * \param rnr Region number to be configured. * \param rbar Value for RBAR register. * \param rlar Value for RLAR register. */ __STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar) { ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar); } #endif /** Memcopy with strictly ordered memory access, e.g. for register targets. * \param dst Destination data is copied to. * \param src Source data is copied from. * \param len Amount of data words to be copied. */ __STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) { uint32_t i; for (i = 0U; i < len; ++i) { dst[i] = src[i]; } } /** Load the given number of MPU regions from a table to the given MPU. * \param mpu Pointer to the MPU registers to be used. * \param rnr First region number to be configured. * \param table Pointer to the MPU configuration table. * \param cnt Amount of regions to be configured. */ __STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) { const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; if (cnt == 1U) { mpu->RNR = rnr; ARM_MPU_OrderedMemcpy(&(mpu->RBAR), &(table->RBAR), rowWordSize); } else { uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U); uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES; mpu->RNR = rnrBase; while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) { uint32_t c = MPU_TYPE_RALIASES - rnrOffset; ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize); table += c; cnt -= c; rnrOffset = 0U; rnrBase += MPU_TYPE_RALIASES; mpu->RNR = rnrBase; } ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize); } } /** Load the given number of MPU regions from a table. * \param rnr First region number to be configured. * \param table Pointer to the MPU configuration table. * \param cnt Amount of regions to be configured. */ __STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) { ARM_MPU_LoadEx(MPU, rnr, table, cnt); } #ifdef MPU_NS /** Load the given number of MPU regions from a table to the Non-secure MPU. * \param rnr First region number to be configured. * \param table Pointer to the MPU configuration table. * \param cnt Amount of regions to be configured. */ __STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) { ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt); } #endif #endif ================================================ FILE: 3rd_party/CMSIS/Include/tz_context.h ================================================ /****************************************************************************** * @file tz_context.h * @brief Context Management for Armv8-M TrustZone * @version V1.0.1 * @date 10. January 2018 ******************************************************************************/ /* * Copyright (c) 2017-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef TZ_CONTEXT_H #define TZ_CONTEXT_H #include #ifndef TZ_MODULEID_T #define TZ_MODULEID_T /// \details Data type that identifies secure software modules called by a process. typedef uint32_t TZ_ModuleId_t; #endif /// \details TZ Memory ID identifies an allocated memory slot. typedef uint32_t TZ_MemoryId_t; /// Initialize secure context memory system /// \return execution status (1: success, 0: error) uint32_t TZ_InitContextSystem_S (void); /// Allocate context memory for calling secure software modules in TrustZone /// \param[in] module identifies software modules called from non-secure mode /// \return value != 0 id TrustZone memory slot identifier /// \return value 0 no memory available or internal error TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module); /// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S /// \param[in] id TrustZone memory slot identifier /// \return execution status (1: success, 0: error) uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id); /// Load secure context (called on RTOS thread context switch) /// \param[in] id TrustZone memory slot identifier /// \return execution status (1: success, 0: error) uint32_t TZ_LoadContext_S (TZ_MemoryId_t id); /// Store secure context (called on RTOS thread context switch) /// \param[in] id TrustZone memory slot identifier /// \return execution status (1: success, 0: error) uint32_t TZ_StoreContext_S (TZ_MemoryId_t id); #endif // TZ_CONTEXT_H ================================================ FILE: 3rd_party/CMSIS/LICENSE.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: 3rd_party/CMSIS/README.txt ================================================ About CMSIS =========== This folder contains the Cortex Microcontroller Software Interface Standard CMSIS 5.6.0 (https://github.com/ARM-software/CMSIS_5/releases/tag/5.6.0). CMSIS provides a single standard across all Cortex-M processor series vendors. It enables code re-use and code sharing across software projects and reduces time-to-market for new embedded applications. Licensing ========= CMSIS-5 is released under the terms of the Apache License Version 2.0 included in the file LICENSE.txt. Complete Downloads ================== To reduce the size of the distribution, this CMSIS folder contains only the Include sub-directory. The complete CMSIS-5 is available at: https://github.com/ARM-software/CMSIS_5 ================================================ FILE: 3rd_party/ek-tm4c123gxl/README.txt ================================================ This directory contains the support code for the EK-TM4C123GXL board (TivaC LauchPad). The sub-directories contain code that is specific to the particular ARM toolchains, such as ARM (MDK-ARM), GCC, and IAR. CMSIS-Compliant Device Files ============================ The code also includes the CMSIS-compliant interface to the TM4C123GH6PM MCU files: TM4C123GH6PM.h system_TM4C123GH6PM.h system_TM4C123GH6PM.c arm\startup_TM4C123GH6PM.s gcc\startup_TM4C123GH6PM.c iar\startup_TM4C123GH6PM.s Adjusting the CPU Clock Speed ----------------------------- The current setting is to run at 50MHz from PLL, but the CPU clock speed can be modified by editing the file system_TM4C123GH6PM.c. ================================================ FILE: 3rd_party/ek-tm4c123gxl/TM4C123GH6PM.h ================================================ /***************************************************************************** * Modified from the original as follows: * - defined TARGET_IS_BLIZZARD_RA1 for compatibility with the TI library * - in GPIOA_Type struct replaced first __I RESERVED0[255] with * __IO uint32_t DATA_Bits[255] to access the individual GPIOA bits. * - added options for the ARMCC v6 compiler (CLANG) * * Quantum Leaps on 2018-01-31 * https://www.state-machine.com *****************************************************************************/ /****************************************************************************************************//** * @file TM4C123GH6PM.h * * @brief CMSIS Cortex-M4 Peripheral Access Layer Header File for * TM4C123GH6PM from Texas Instruments. * * @version V12591 * @date 19. February 2014 * * @note Generated with SVDConv V2.79v * from CMSIS SVD File 'TM4C123GH6PM.svd.xml' Version 12591, * * @par * Software License Agreement * * Texas Instruments (TI) is supplying this software for use solely and * exclusively on TI's microcontroller products. The software is owned by * TI and/or its suppliers, and is protected under applicable copyright * laws. You may not combine this software with "viral" open-source * software in order to form a larger program. * * THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. * NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT * NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY * CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL * DAMAGES, FOR ANY REASON WHATSOEVER. * * * *******************************************************************************************************/ /** @addtogroup Texas Instruments * @{ */ /** @addtogroup TM4C123GH6PM * @{ */ #ifndef TM4C123GH6PM_H #define TM4C123GH6PM_H #ifdef __cplusplus extern "C" { #endif /* ------------------------- Interrupt Number Definition ------------------------ */ typedef enum { /* ------------------- Cortex-M4 Processor Exceptions Numbers ------------------- */ Reset_IRQn = -15, /*!< 1 Reset Vector, invoked on Power up and warm reset */ NonMaskableInt_IRQn = -14, /*!< 2 Non maskable Interrupt, cannot be stopped or preempted */ HardFault_IRQn = -13, /*!< 3 Hard Fault, all classes of Fault */ MemoryManagement_IRQn = -12, /*!< 4 Memory Management, MPU mismatch, including Access Violation and No Match */ BusFault_IRQn = -11, /*!< 5 Bus Fault, Pre-Fetch-, Memory Access Fault, other address/memory related Fault */ UsageFault_IRQn = -10, /*!< 6 Usage Fault, i.e. Undef Instruction, Illegal State Transition */ SVCall_IRQn = -5, /*!< 11 System Service Call via SVC instruction */ DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor */ PendSV_IRQn = -2, /*!< 14 Pendable request for system service */ SysTick_IRQn = -1, /*!< 15 System Tick Timer */ /* ------------------- TM4C123GH6PM Specific Interrupt Numbers ------------------ */ GPIOA_IRQn = 0, /*!< 0 GPIOA */ GPIOB_IRQn = 1, /*!< 1 GPIOB */ GPIOC_IRQn = 2, /*!< 2 GPIOC */ GPIOD_IRQn = 3, /*!< 3 GPIOD */ GPIOE_IRQn = 4, /*!< 4 GPIOE */ UART0_IRQn = 5, /*!< 5 UART0 */ UART1_IRQn = 6, /*!< 6 UART1 */ SSI0_IRQn = 7, /*!< 7 SSI0 */ I2C0_IRQn = 8, /*!< 8 I2C0 */ PWM0_FAULT_IRQn = 9, /*!< 9 PWM0_FAULT */ PWM0_0_IRQn = 10, /*!< 10 PWM0_0 */ PWM0_1_IRQn = 11, /*!< 11 PWM0_1 */ PWM0_2_IRQn = 12, /*!< 12 PWM0_2 */ QEI0_IRQn = 13, /*!< 13 QEI0 */ ADC0SS0_IRQn = 14, /*!< 14 ADC0SS0 */ ADC0SS1_IRQn = 15, /*!< 15 ADC0SS1 */ ADC0SS2_IRQn = 16, /*!< 16 ADC0SS2 */ ADC0SS3_IRQn = 17, /*!< 17 ADC0SS3 */ WATCHDOG0_IRQn = 18, /*!< 18 WATCHDOG0 */ TIMER0A_IRQn = 19, /*!< 19 TIMER0A */ TIMER0B_IRQn = 20, /*!< 20 TIMER0B */ TIMER1A_IRQn = 21, /*!< 21 TIMER1A */ TIMER1B_IRQn = 22, /*!< 22 TIMER1B */ TIMER2A_IRQn = 23, /*!< 23 TIMER2A */ TIMER2B_IRQn = 24, /*!< 24 TIMER2B */ COMP0_IRQn = 25, /*!< 25 COMP0 */ COMP1_IRQn = 26, /*!< 26 COMP1 */ SYSCTL_IRQn = 28, /*!< 28 SYSCTL */ FLASH_CTRL_IRQn = 29, /*!< 29 FLASH_CTRL */ GPIOF_IRQn = 30, /*!< 30 GPIOF */ UART2_IRQn = 33, /*!< 33 UART2 */ SSI1_IRQn = 34, /*!< 34 SSI1 */ TIMER3A_IRQn = 35, /*!< 35 TIMER3A */ TIMER3B_IRQn = 36, /*!< 36 TIMER3B */ I2C1_IRQn = 37, /*!< 37 I2C1 */ QEI1_IRQn = 38, /*!< 38 QEI1 */ CAN0_IRQn = 39, /*!< 39 CAN0 */ CAN1_IRQn = 40, /*!< 40 CAN1 */ HIB_IRQn = 43, /*!< 43 HIB */ USB0_IRQn = 44, /*!< 44 USB0 */ PWM0_3_IRQn = 45, /*!< 45 PWM0_3 */ UDMA_IRQn = 46, /*!< 46 UDMA */ UDMAERR_IRQn = 47, /*!< 47 UDMAERR */ ADC1SS0_IRQn = 48, /*!< 48 ADC1SS0 */ ADC1SS1_IRQn = 49, /*!< 49 ADC1SS1 */ ADC1SS2_IRQn = 50, /*!< 50 ADC1SS2 */ ADC1SS3_IRQn = 51, /*!< 51 ADC1SS3 */ SSI2_IRQn = 57, /*!< 57 SSI2 */ SSI3_IRQn = 58, /*!< 58 SSI3 */ UART3_IRQn = 59, /*!< 59 UART3 */ UART4_IRQn = 60, /*!< 60 UART4 */ UART5_IRQn = 61, /*!< 61 UART5 */ UART6_IRQn = 62, /*!< 62 UART6 */ UART7_IRQn = 63, /*!< 63 UART7 */ I2C2_IRQn = 68, /*!< 68 I2C2 */ I2C3_IRQn = 69, /*!< 69 I2C3 */ TIMER4A_IRQn = 70, /*!< 70 TIMER4A */ TIMER4B_IRQn = 71, /*!< 71 TIMER4B */ TIMER5A_IRQn = 92, /*!< 92 TIMER5A */ TIMER5B_IRQn = 93, /*!< 93 TIMER5B */ WTIMER0A_IRQn = 94, /*!< 94 WTIMER0A */ WTIMER0B_IRQn = 95, /*!< 95 WTIMER0B */ WTIMER1A_IRQn = 96, /*!< 96 WTIMER1A */ WTIMER1B_IRQn = 97, /*!< 97 WTIMER1B */ WTIMER2A_IRQn = 98, /*!< 98 WTIMER2A */ WTIMER2B_IRQn = 99, /*!< 99 WTIMER2B */ WTIMER3A_IRQn = 100, /*!< 100 WTIMER3A */ WTIMER3B_IRQn = 101, /*!< 101 WTIMER3B */ WTIMER4A_IRQn = 102, /*!< 102 WTIMER4A */ WTIMER4B_IRQn = 103, /*!< 103 WTIMER4B */ WTIMER5A_IRQn = 104, /*!< 104 WTIMER5A */ WTIMER5B_IRQn = 105, /*!< 105 WTIMER5B */ SYSEXC_IRQn = 106, /*!< 106 SYSEXC */ PWM1_0_IRQn = 134, /*!< 134 PWM1_0 */ PWM1_1_IRQn = 135, /*!< 135 PWM1_1 */ PWM1_2_IRQn = 136, /*!< 136 PWM1_2 */ PWM1_3_IRQn = 137, /*!< 137 PWM1_3 */ PWM1_FAULT_IRQn = 138 /*!< 138 PWM1_FAULT */ } IRQn_Type; /* * =========================================================================== * ---------- Interrupt Handler Prototypes ----------------------------------- * =========================================================================== */ void NMI_Handler(void); void HardFault_Handler(void); void MemManage_Handler(void); void BusFault_Handler(void); void UsageFault_Handler(void); void HardFault_Handler(void); void SVC_Handler(void); void DebugMon_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); void GPIOPortA_IRQHandler(void); void GPIOPortB_IRQHandler(void); void GPIOPortC_IRQHandler(void); void GPIOPortD_IRQHandler(void); void GPIOPortE_IRQHandler(void); void UART0_IRQHandler(void); void UART1_IRQHandler(void); void SSI0_IRQHandler(void); void I2C0_IRQHandler(void); void PWMFault_IRQHandler(void); void PWMGen0_IRQHandler(void); void PWMGen1_IRQHandler(void); void PWMGen2_IRQHandler(void); void QEI0_IRQHandler(void); void ADCSeq0_IRQHandler(void); void ADCSeq1_IRQHandler(void); void ADCSeq2_IRQHandler(void); void ADCSeq3_IRQHandler(void); void Watchdog_IRQHandler(void); void Timer0A_IRQHandler(void); void Timer0B_IRQHandler(void); void Timer1A_IRQHandler(void); void Timer1B_IRQHandler(void); void Timer2A_IRQHandler(void); void Timer2B_IRQHandler(void); void Comp0_IRQHandler(void); void Comp1_IRQHandler(void); void Comp2_IRQHandler(void); void SysCtrl_IRQHandler(void); void FlashCtrl_IRQHandler(void); void GPIOPortF_IRQHandler(void); void GPIOPortG_IRQHandler(void); void GPIOPortH_IRQHandler(void); void UART2_IRQHandler(void); void SSI1_IRQHandler(void); void Timer3A_IRQHandler(void); void Timer3B_IRQHandler(void); void I2C1_IRQHandler(void); void QEI1_IRQHandler(void); void CAN0_IRQHandler(void); void CAN1_IRQHandler(void); void CAN2_IRQHandler(void); void Hibernate_IRQHandler(void); void USB0_IRQHandler(void); void PWMGen3_IRQHandler(void); void uDMAST_IRQHandler(void); void uDMAError_IRQHandler(void); void ADC1Seq0_IRQHandler(void); void ADC1Seq1_IRQHandler(void); void ADC1Seq2_IRQHandler(void); void ADC1Seq3_IRQHandler(void); void I2S0_IRQHandler(void); void EBI0_IRQHandler(void); void GPIOPortJ_IRQHandler(void); void GPIOPortK_IRQHandler(void); void GPIOPortL_IRQHandler(void); void SSI2_IRQHandler(void); void SSI3_IRQHandler(void); void UART3_IRQHandler(void); void UART4_IRQHandler(void); void UART5_IRQHandler(void); void UART6_IRQHandler(void); void UART7_IRQHandler(void); void I2C2_IRQHandler(void); void I2C3_IRQHandler(void); void Timer4A_IRQHandler(void); void Timer4B_IRQHandler(void); void Timer5A_IRQHandler(void); void Timer5B_IRQHandler(void); void WideTimer0A_IRQHandler(void); void WideTimer0B_IRQHandler(void); void WideTimer1A_IRQHandler(void); void WideTimer1B_IRQHandler(void); void WideTimer2A_IRQHandler(void); void WideTimer2B_IRQHandler(void); void WideTimer3A_IRQHandler(void); void WideTimer3B_IRQHandler(void); void WideTimer4A_IRQHandler(void); void WideTimer4B_IRQHandler(void); void WideTimer5A_IRQHandler(void); void WideTimer5B_IRQHandler(void); void FPU_IRQHandler(void); void PECI0_IRQHandler(void); void LPC0_IRQHandler(void); void I2C4_IRQHandler(void); void I2C5_IRQHandler(void); void GPIOPortM_IRQHandler(void); void GPIOPortN_IRQHandler(void); void QEI2_IRQHandler(void); void Fan0_IRQHandler(void); void GPIOPortP0_IRQHandler(void); void GPIOPortP1_IRQHandler(void); void GPIOPortP2_IRQHandler(void); void GPIOPortP3_IRQHandler(void); void GPIOPortP4_IRQHandler(void); void GPIOPortP5_IRQHandler(void); void GPIOPortP6_IRQHandler(void); void GPIOPortP7_IRQHandler(void); void GPIOPortQ0_IRQHandler(void); void GPIOPortQ1_IRQHandler(void); void GPIOPortQ2_IRQHandler(void); void GPIOPortQ3_IRQHandler(void); void GPIOPortQ4_IRQHandler(void); void GPIOPortQ5_IRQHandler(void); void GPIOPortQ6_IRQHandler(void); void GPIOPortQ7_IRQHandler(void); void GPIOPortR_IRQHandler(void); void GPIOPortS_IRQHandler(void); void PWM1Gen0_IRQHandler(void); void PWM1Gen1_IRQHandler(void); void PWM1Gen2_IRQHandler(void); void PWM1Gen3_IRQHandler(void); void PWM1Fault_IRQHandler(void); /** @addtogroup Configuration_of_CMSIS * @{ */ /* ================================================================================ */ /* ================ Processor and Core Peripheral Section ================ */ /* ================================================================================ */ /* ----------------Configuration of the Cortex-M4 Processor and Core Peripherals---------------- */ #define __CM4_REV 0x0102 /*!< Cortex-M4 Core Revision */ #define __MPU_PRESENT 1 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */ #define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ #define __FPU_PRESENT 1 /*!< FPU present or not */ #define TARGET_IS_BLIZZARD_RA1 1 /*!< Class of device (for TI library) */ /** @} */ /* End of group Configuration_of_CMSIS */ #ifdef __cplusplus } #endif #include "core_cm4.h" /*!< Cortex-M4 processor and core peripherals */ #include "system_TM4C123GH6PM.h" /*!< TM4C123GH6PM System */ /* ================================================================================ */ /* ================ Device Specific Peripheral Section ================ */ /* ================================================================================ */ #ifdef __cplusplus extern "C" { #endif /** @addtogroup Device_Peripheral_Registers * @{ */ /* ------------------- Start of section using anonymous unions ------------------ */ #if defined(__CC_ARM) #pragma push #pragma anon_unions #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* anonymous unions are enabled by default */ #elif defined(__ICCARM__) #pragma language=extended #elif defined(__GNUC__) /* anonymous unions are enabled by default */ #elif defined(__TMS470__) /* anonymous unions are enabled by default */ #elif defined(__TASKING__) #pragma warning 586 #else #warning Not supported compiler type #endif /* ================================================================================ */ /* ================ WATCHDOG0 ================ */ /* ================================================================================ */ /** * @brief Register map for WATCHDOG0 peripheral (WATCHDOG0) */ typedef struct { /*!< WATCHDOG0 Structure */ __IO uint32_t LOAD; /*!< Watchdog Load */ __IO uint32_t VALUE; /*!< Watchdog Value */ __IO uint32_t CTL; /*!< Watchdog Control */ __O uint32_t ICR; /*!< Watchdog Interrupt Clear */ __IO uint32_t RIS; /*!< Watchdog Raw Interrupt Status */ __IO uint32_t MIS; /*!< Watchdog Masked Interrupt Status */ __I uint32_t RESERVED0[256]; __IO uint32_t TEST; /*!< Watchdog Test */ __I uint32_t RESERVED1[505]; __IO uint32_t LOCK; /*!< Watchdog Lock */ } WATCHDOG0_Type; /* ================================================================================ */ /* ================ GPIOA ================ */ /* ================================================================================ */ /** * @brief Register map for GPIOA peripheral (GPIOA) */ typedef struct { /*!< GPIOA Structure */ __IO uint32_t DATA_Bits[255]; /*!< GPIO bit combinations */ __IO uint32_t DATA; /*!< GPIO Data */ __IO uint32_t DIR; /*!< GPIO Direction */ __IO uint32_t IS; /*!< GPIO Interrupt Sense */ __IO uint32_t IBE; /*!< GPIO Interrupt Both Edges */ __IO uint32_t IEV; /*!< GPIO Interrupt Event */ __IO uint32_t IM; /*!< GPIO Interrupt Mask */ __IO uint32_t RIS; /*!< GPIO Raw Interrupt Status */ __IO uint32_t MIS; /*!< GPIO Masked Interrupt Status */ __O uint32_t ICR; /*!< GPIO Interrupt Clear */ __IO uint32_t AFSEL; /*!< GPIO Alternate Function Select */ __I uint32_t RESERVED1[55]; __IO uint32_t DR2R; /*!< GPIO 2-mA Drive Select */ __IO uint32_t DR4R; /*!< GPIO 4-mA Drive Select */ __IO uint32_t DR8R; /*!< GPIO 8-mA Drive Select */ __IO uint32_t ODR; /*!< GPIO Open Drain Select */ __IO uint32_t PUR; /*!< GPIO Pull-Up Select */ __IO uint32_t PDR; /*!< GPIO Pull-Down Select */ __IO uint32_t SLR; /*!< GPIO Slew Rate Control Select */ __IO uint32_t DEN; /*!< GPIO Digital Enable */ __IO uint32_t LOCK; /*!< GPIO Lock */ __I uint32_t CR; /*!< GPIO Commit */ __IO uint32_t AMSEL; /*!< GPIO Analog Mode Select */ __IO uint32_t PCTL; /*!< GPIO Port Control */ __IO uint32_t ADCCTL; /*!< GPIO ADC Control */ __IO uint32_t DMACTL; /*!< GPIO DMA Control */ } GPIOA_Type; /* ================================================================================ */ /* ================ SSI0 ================ */ /* ================================================================================ */ /** * @brief Register map for SSI0 peripheral (SSI0) */ typedef struct { /*!< SSI0 Structure */ __IO uint32_t CR0; /*!< SSI Control 0 */ __IO uint32_t CR1; /*!< SSI Control 1 */ __IO uint32_t DR; /*!< SSI Data */ __IO uint32_t SR; /*!< SSI Status */ __IO uint32_t CPSR; /*!< SSI Clock Prescale */ __IO uint32_t IM; /*!< SSI Interrupt Mask */ __IO uint32_t RIS; /*!< SSI Raw Interrupt Status */ __IO uint32_t MIS; /*!< SSI Masked Interrupt Status */ __O uint32_t ICR; /*!< SSI Interrupt Clear */ __IO uint32_t DMACTL; /*!< SSI DMA Control */ __I uint32_t RESERVED0[1000]; __IO uint32_t CC; /*!< SSI Clock Configuration */ } SSI0_Type; /* ================================================================================ */ /* ================ UART0 ================ */ /* ================================================================================ */ /** * @brief Register map for UART0 peripheral (UART0) */ typedef struct { /*!< UART0 Structure */ __IO uint32_t DR; /*!< UART Data */ union { __IO uint32_t ECR_UART_ALT; /*!< UART Receive Status/Error Clear */ __IO uint32_t RSR; /*!< UART Receive Status/Error Clear */ }; __I uint32_t RESERVED0[4]; __IO uint32_t FR; /*!< UART Flag */ __I uint32_t RESERVED1; __IO uint32_t ILPR; /*!< UART IrDA Low-Power Register */ __IO uint32_t IBRD; /*!< UART Integer Baud-Rate Divisor */ __IO uint32_t FBRD; /*!< UART Fractional Baud-Rate Divisor */ __IO uint32_t LCRH; /*!< UART Line Control */ __IO uint32_t CTL; /*!< UART Control */ __IO uint32_t IFLS; /*!< UART Interrupt FIFO Level Select */ __IO uint32_t IM; /*!< UART Interrupt Mask */ __IO uint32_t RIS; /*!< UART Raw Interrupt Status */ __IO uint32_t MIS; /*!< UART Masked Interrupt Status */ __O uint32_t ICR; /*!< UART Interrupt Clear */ __IO uint32_t DMACTL; /*!< UART DMA Control */ __I uint32_t RESERVED2[22]; __IO uint32_t _9BITADDR; /*!< UART 9-Bit Self Address */ __IO uint32_t _9BITAMASK; /*!< UART 9-Bit Self Address Mask */ __I uint32_t RESERVED3[965]; __IO uint32_t PP; /*!< UART Peripheral Properties */ __I uint32_t RESERVED4; __IO uint32_t CC; /*!< UART Clock Configuration */ } UART0_Type; /* ================================================================================ */ /* ================ I2C0 ================ */ /* ================================================================================ */ /** * @brief Register map for I2C0 peripheral (I2C0) */ typedef struct { /*!< I2C0 Structure */ __IO uint32_t MSA; /*!< I2C Master Slave Address */ union { __IO uint32_t MCS_I2C0_ALT; /*!< I2C Master Control/Status */ __IO uint32_t MCS; /*!< I2C Master Control/Status */ }; __IO uint32_t MDR; /*!< I2C Master Data */ __IO uint32_t MTPR; /*!< I2C Master Timer Period */ __IO uint32_t MIMR; /*!< I2C Master Interrupt Mask */ __IO uint32_t MRIS; /*!< I2C Master Raw Interrupt Status */ __IO uint32_t MMIS; /*!< I2C Master Masked Interrupt Status */ __O uint32_t MICR; /*!< I2C Master Interrupt Clear */ __IO uint32_t MCR; /*!< I2C Master Configuration */ __IO uint32_t MCLKOCNT; /*!< I2C Master Clock Low Timeout Count */ __I uint32_t RESERVED0; __IO uint32_t MBMON; /*!< I2C Master Bus Monitor */ __I uint32_t RESERVED1[2]; __IO uint32_t MCR2; /*!< I2C Master Configuration 2 */ __I uint32_t RESERVED2[497]; __IO uint32_t SOAR; /*!< I2C Slave Own Address */ union { __IO uint32_t SCSR_I2C0_ALT; /*!< I2C Slave Control/Status */ __IO uint32_t SCSR; /*!< I2C Slave Control/Status */ }; __IO uint32_t SDR; /*!< I2C Slave Data */ __IO uint32_t SIMR; /*!< I2C Slave Interrupt Mask */ __IO uint32_t SRIS; /*!< I2C Slave Raw Interrupt Status */ __IO uint32_t SMIS; /*!< I2C Slave Masked Interrupt Status */ __O uint32_t SICR; /*!< I2C Slave Interrupt Clear */ __IO uint32_t SOAR2; /*!< I2C Slave Own Address 2 */ __IO uint32_t SACKCTL; /*!< I2C Slave ACK Control */ __I uint32_t RESERVED3[487]; __IO uint32_t PP; /*!< I2C Peripheral Properties */ __IO uint32_t PC; /*!< I2C Peripheral Configuration */ } I2C0_Type; /* ================================================================================ */ /* ================ PWM0 ================ */ /* ================================================================================ */ /** * @brief Register map for PWM0 peripheral (PWM0) */ typedef struct { /*!< PWM0 Structure */ __IO uint32_t CTL; /*!< PWM Master Control */ __IO uint32_t SYNC; /*!< PWM Time Base Sync */ __IO uint32_t ENABLE; /*!< PWM Output Enable */ __IO uint32_t INVERT; /*!< PWM Output Inversion */ __IO uint32_t FAULT; /*!< PWM Output Fault */ __IO uint32_t INTEN; /*!< PWM Interrupt Enable */ __IO uint32_t RIS; /*!< PWM Raw Interrupt Status */ __IO uint32_t ISC; /*!< PWM Interrupt Status and Clear */ __IO uint32_t STATUS; /*!< PWM Status */ __IO uint32_t FAULTVAL; /*!< PWM Fault Condition Value */ __IO uint32_t ENUPD; /*!< PWM Enable Update */ __I uint32_t RESERVED0[5]; __IO uint32_t _0_CTL; /*!< PWM0 Control */ __IO uint32_t _0_INTEN; /*!< PWM0 Interrupt and Trigger Enable */ __IO uint32_t _0_RIS; /*!< PWM0 Raw Interrupt Status */ __IO uint32_t _0_ISC; /*!< PWM0 Interrupt Status and Clear */ __IO uint32_t _0_LOAD; /*!< PWM0 Load */ __IO uint32_t _0_COUNT; /*!< PWM0 Counter */ __IO uint32_t _0_CMPA; /*!< PWM0 Compare A */ __IO uint32_t _0_CMPB; /*!< PWM0 Compare B */ __IO uint32_t _0_GENA; /*!< PWM0 Generator A Control */ __IO uint32_t _0_GENB; /*!< PWM0 Generator B Control */ __IO uint32_t _0_DBCTL; /*!< PWM0 Dead-Band Control */ __IO uint32_t _0_DBRISE; /*!< PWM0 Dead-Band Rising-Edge Delay */ __IO uint32_t _0_DBFALL; /*!< PWM0 Dead-Band Falling-Edge-Delay */ __IO uint32_t _0_FLTSRC0; /*!< PWM0 Fault Source 0 */ __IO uint32_t _0_FLTSRC1; /*!< PWM0 Fault Source 1 */ __IO uint32_t _0_MINFLTPER; /*!< PWM0 Minimum Fault Period */ __IO uint32_t _1_CTL; /*!< PWM1 Control */ __IO uint32_t _1_INTEN; /*!< PWM1 Interrupt and Trigger Enable */ __IO uint32_t _1_RIS; /*!< PWM1 Raw Interrupt Status */ __IO uint32_t _1_ISC; /*!< PWM1 Interrupt Status and Clear */ __IO uint32_t _1_LOAD; /*!< PWM1 Load */ __IO uint32_t _1_COUNT; /*!< PWM1 Counter */ __IO uint32_t _1_CMPA; /*!< PWM1 Compare A */ __IO uint32_t _1_CMPB; /*!< PWM1 Compare B */ __IO uint32_t _1_GENA; /*!< PWM1 Generator A Control */ __IO uint32_t _1_GENB; /*!< PWM1 Generator B Control */ __IO uint32_t _1_DBCTL; /*!< PWM1 Dead-Band Control */ __IO uint32_t _1_DBRISE; /*!< PWM1 Dead-Band Rising-Edge Delay */ __IO uint32_t _1_DBFALL; /*!< PWM1 Dead-Band Falling-Edge-Delay */ __IO uint32_t _1_FLTSRC0; /*!< PWM1 Fault Source 0 */ __IO uint32_t _1_FLTSRC1; /*!< PWM1 Fault Source 1 */ __IO uint32_t _1_MINFLTPER; /*!< PWM1 Minimum Fault Period */ __IO uint32_t _2_CTL; /*!< PWM2 Control */ __IO uint32_t _2_INTEN; /*!< PWM2 Interrupt and Trigger Enable */ __IO uint32_t _2_RIS; /*!< PWM2 Raw Interrupt Status */ __IO uint32_t _2_ISC; /*!< PWM2 Interrupt Status and Clear */ __IO uint32_t _2_LOAD; /*!< PWM2 Load */ __IO uint32_t _2_COUNT; /*!< PWM2 Counter */ __IO uint32_t _2_CMPA; /*!< PWM2 Compare A */ __IO uint32_t _2_CMPB; /*!< PWM2 Compare B */ __IO uint32_t _2_GENA; /*!< PWM2 Generator A Control */ __IO uint32_t _2_GENB; /*!< PWM2 Generator B Control */ __IO uint32_t _2_DBCTL; /*!< PWM2 Dead-Band Control */ __IO uint32_t _2_DBRISE; /*!< PWM2 Dead-Band Rising-Edge Delay */ __IO uint32_t _2_DBFALL; /*!< PWM2 Dead-Band Falling-Edge-Delay */ __IO uint32_t _2_FLTSRC0; /*!< PWM2 Fault Source 0 */ __IO uint32_t _2_FLTSRC1; /*!< PWM2 Fault Source 1 */ __IO uint32_t _2_MINFLTPER; /*!< PWM2 Minimum Fault Period */ __IO uint32_t _3_CTL; /*!< PWM3 Control */ __IO uint32_t _3_INTEN; /*!< PWM3 Interrupt and Trigger Enable */ __IO uint32_t _3_RIS; /*!< PWM3 Raw Interrupt Status */ __IO uint32_t _3_ISC; /*!< PWM3 Interrupt Status and Clear */ __IO uint32_t _3_LOAD; /*!< PWM3 Load */ __IO uint32_t _3_COUNT; /*!< PWM3 Counter */ __IO uint32_t _3_CMPA; /*!< PWM3 Compare A */ __IO uint32_t _3_CMPB; /*!< PWM3 Compare B */ __IO uint32_t _3_GENA; /*!< PWM3 Generator A Control */ __IO uint32_t _3_GENB; /*!< PWM3 Generator B Control */ __IO uint32_t _3_DBCTL; /*!< PWM3 Dead-Band Control */ __IO uint32_t _3_DBRISE; /*!< PWM3 Dead-Band Rising-Edge Delay */ __IO uint32_t _3_DBFALL; /*!< PWM3 Dead-Band Falling-Edge-Delay */ __IO uint32_t _3_FLTSRC0; /*!< PWM3 Fault Source 0 */ __IO uint32_t _3_FLTSRC1; /*!< PWM3 Fault Source 1 */ __IO uint32_t _3_MINFLTPER; /*!< PWM3 Minimum Fault Period */ __I uint32_t RESERVED1[432]; __IO uint32_t _0_FLTSEN; /*!< PWM0 Fault Pin Logic Sense */ __I uint32_t _0_FLTSTAT0; /*!< PWM0 Fault Status 0 */ __I uint32_t _0_FLTSTAT1; /*!< PWM0 Fault Status 1 */ __I uint32_t RESERVED2[29]; __IO uint32_t _1_FLTSEN; /*!< PWM1 Fault Pin Logic Sense */ __I uint32_t _1_FLTSTAT0; /*!< PWM1 Fault Status 0 */ __I uint32_t _1_FLTSTAT1; /*!< PWM1 Fault Status 1 */ __I uint32_t RESERVED3[30]; __I uint32_t _2_FLTSTAT0; /*!< PWM2 Fault Status 0 */ __I uint32_t _2_FLTSTAT1; /*!< PWM2 Fault Status 1 */ __I uint32_t RESERVED4[30]; __I uint32_t _3_FLTSTAT0; /*!< PWM3 Fault Status 0 */ __I uint32_t _3_FLTSTAT1; /*!< PWM3 Fault Status 1 */ __I uint32_t RESERVED5[397]; __IO uint32_t PP; /*!< PWM Peripheral Properties */ } PWM0_Type; /* ================================================================================ */ /* ================ QEI0 ================ */ /* ================================================================================ */ /** * @brief Register map for QEI0 peripheral (QEI0) */ typedef struct { /*!< QEI0 Structure */ __IO uint32_t CTL; /*!< QEI Control */ __IO uint32_t STAT; /*!< QEI Status */ __IO uint32_t POS; /*!< QEI Position */ __IO uint32_t MAXPOS; /*!< QEI Maximum Position */ __IO uint32_t LOAD; /*!< QEI Timer Load */ __IO uint32_t TIME; /*!< QEI Timer */ __IO uint32_t COUNT; /*!< QEI Velocity Counter */ __IO uint32_t SPEED; /*!< QEI Velocity */ __IO uint32_t INTEN; /*!< QEI Interrupt Enable */ __IO uint32_t RIS; /*!< QEI Raw Interrupt Status */ __IO uint32_t ISC; /*!< QEI Interrupt Status and Clear */ } QEI0_Type; /* ================================================================================ */ /* ================ TIMER0 ================ */ /* ================================================================================ */ /** * @brief Register map for TIMER0 peripheral (TIMER0) */ typedef struct { /*!< TIMER0 Structure */ __IO uint32_t CFG; /*!< GPTM Configuration */ __IO uint32_t TAMR; /*!< GPTM Timer A Mode */ __IO uint32_t TBMR; /*!< GPTM Timer B Mode */ __IO uint32_t CTL; /*!< GPTM Control */ __IO uint32_t SYNC; /*!< GPTM Synchronize */ __I uint32_t RESERVED0; __IO uint32_t IMR; /*!< GPTM Interrupt Mask */ __IO uint32_t RIS; /*!< GPTM Raw Interrupt Status */ __IO uint32_t MIS; /*!< GPTM Masked Interrupt Status */ __O uint32_t ICR; /*!< GPTM Interrupt Clear */ __IO uint32_t TAILR; /*!< GPTM Timer A Interval Load */ __IO uint32_t TBILR; /*!< GPTM Timer B Interval Load */ __IO uint32_t TAMATCHR; /*!< GPTM Timer A Match */ __IO uint32_t TBMATCHR; /*!< GPTM Timer B Match */ __IO uint32_t TAPR; /*!< GPTM Timer A Prescale */ __IO uint32_t TBPR; /*!< GPTM Timer B Prescale */ __IO uint32_t TAPMR; /*!< GPTM TimerA Prescale Match */ __IO uint32_t TBPMR; /*!< GPTM TimerB Prescale Match */ __IO uint32_t TAR; /*!< GPTM Timer A */ __IO uint32_t TBR; /*!< GPTM Timer B */ __IO uint32_t TAV; /*!< GPTM Timer A Value */ __IO uint32_t TBV; /*!< GPTM Timer B Value */ __IO uint32_t RTCPD; /*!< GPTM RTC Predivide */ __IO uint32_t TAPS; /*!< GPTM Timer A Prescale Snapshot */ __IO uint32_t TBPS; /*!< GPTM Timer B Prescale Snapshot */ __IO uint32_t TAPV; /*!< GPTM Timer A Prescale Value */ __IO uint32_t TBPV; /*!< GPTM Timer B Prescale Value */ __I uint32_t RESERVED1[981]; __IO uint32_t PP; /*!< GPTM Peripheral Properties */ } TIMER0_Type; /* ================================================================================ */ /* ================ WTIMER0 ================ */ /* ================================================================================ */ /** * @brief Register map for WTIMER0 peripheral (WTIMER0) */ typedef struct { /*!< WTIMER0 Structure */ __IO uint32_t CFG; /*!< GPTM Configuration */ __IO uint32_t TAMR; /*!< GPTM Timer A Mode */ __IO uint32_t TBMR; /*!< GPTM Timer B Mode */ __IO uint32_t CTL; /*!< GPTM Control */ __IO uint32_t SYNC; /*!< GPTM Synchronize */ __I uint32_t RESERVED0; __IO uint32_t IMR; /*!< GPTM Interrupt Mask */ __IO uint32_t RIS; /*!< GPTM Raw Interrupt Status */ __IO uint32_t MIS; /*!< GPTM Masked Interrupt Status */ __O uint32_t ICR; /*!< GPTM Interrupt Clear */ __IO uint32_t TAILR; /*!< GPTM Timer A Interval Load */ __IO uint32_t TBILR; /*!< GPTM Timer B Interval Load */ __IO uint32_t TAMATCHR; /*!< GPTM Timer A Match */ __IO uint32_t TBMATCHR; /*!< GPTM Timer B Match */ __IO uint32_t TAPR; /*!< GPTM Timer A Prescale */ __IO uint32_t TBPR; /*!< GPTM Timer B Prescale */ __IO uint32_t TAPMR; /*!< GPTM TimerA Prescale Match */ __IO uint32_t TBPMR; /*!< GPTM TimerB Prescale Match */ __IO uint32_t TAR; /*!< GPTM Timer A */ __IO uint32_t TBR; /*!< GPTM Timer B */ __IO uint32_t TAV; /*!< GPTM Timer A Value */ __IO uint32_t TBV; /*!< GPTM Timer B Value */ __IO uint32_t RTCPD; /*!< GPTM RTC Predivide */ __IO uint32_t TAPS; /*!< GPTM Timer A Prescale Snapshot */ __IO uint32_t TBPS; /*!< GPTM Timer B Prescale Snapshot */ __IO uint32_t TAPV; /*!< GPTM Timer A Prescale Value */ __IO uint32_t TBPV; /*!< GPTM Timer B Prescale Value */ __I uint32_t RESERVED1[981]; __IO uint32_t PP; /*!< GPTM Peripheral Properties */ } WTIMER0_Type; /* ================================================================================ */ /* ================ ADC0 ================ */ /* ================================================================================ */ /** * @brief Register map for ADC0 peripheral (ADC0) */ typedef struct { /*!< ADC0 Structure */ __IO uint32_t ACTSS; /*!< ADC Active Sample Sequencer */ __IO uint32_t RIS; /*!< ADC Raw Interrupt Status */ __IO uint32_t IM; /*!< ADC Interrupt Mask */ __IO uint32_t ISC; /*!< ADC Interrupt Status and Clear */ __IO uint32_t OSTAT; /*!< ADC Overflow Status */ __IO uint32_t EMUX; /*!< ADC Event Multiplexer Select */ __IO uint32_t USTAT; /*!< ADC Underflow Status */ __IO uint32_t TSSEL; /*!< ADC Trigger Source Select */ __IO uint32_t SSPRI; /*!< ADC Sample Sequencer Priority */ __IO uint32_t SPC; /*!< ADC Sample Phase Control */ __IO uint32_t PSSI; /*!< ADC Processor Sample Sequence Initiate */ __I uint32_t RESERVED0; __IO uint32_t SAC; /*!< ADC Sample Averaging Control */ __IO uint32_t DCISC; /*!< ADC Digital Comparator Interrupt Status and Clear */ __IO uint32_t CTL; /*!< ADC Control */ __I uint32_t RESERVED1; __IO uint32_t SSMUX0; /*!< ADC Sample Sequence Input Multiplexer Select 0 */ __IO uint32_t SSCTL0; /*!< ADC Sample Sequence Control 0 */ __IO uint32_t SSFIFO0; /*!< ADC Sample Sequence Result FIFO 0 */ __IO uint32_t SSFSTAT0; /*!< ADC Sample Sequence FIFO 0 Status */ __IO uint32_t SSOP0; /*!< ADC Sample Sequence 0 Operation */ __IO uint32_t SSDC0; /*!< ADC Sample Sequence 0 Digital Comparator Select */ __I uint32_t RESERVED2[2]; __IO uint32_t SSMUX1; /*!< ADC Sample Sequence Input Multiplexer Select 1 */ __IO uint32_t SSCTL1; /*!< ADC Sample Sequence Control 1 */ __IO uint32_t SSFIFO1; /*!< ADC Sample Sequence Result FIFO 1 */ __IO uint32_t SSFSTAT1; /*!< ADC Sample Sequence FIFO 1 Status */ __IO uint32_t SSOP1; /*!< ADC Sample Sequence 1 Operation */ __IO uint32_t SSDC1; /*!< ADC Sample Sequence 1 Digital Comparator Select */ __I uint32_t RESERVED3[2]; __IO uint32_t SSMUX2; /*!< ADC Sample Sequence Input Multiplexer Select 2 */ __IO uint32_t SSCTL2; /*!< ADC Sample Sequence Control 2 */ __IO uint32_t SSFIFO2; /*!< ADC Sample Sequence Result FIFO 2 */ __IO uint32_t SSFSTAT2; /*!< ADC Sample Sequence FIFO 2 Status */ __IO uint32_t SSOP2; /*!< ADC Sample Sequence 2 Operation */ __IO uint32_t SSDC2; /*!< ADC Sample Sequence 2 Digital Comparator Select */ __I uint32_t RESERVED4[2]; __IO uint32_t SSMUX3; /*!< ADC Sample Sequence Input Multiplexer Select 3 */ __IO uint32_t SSCTL3; /*!< ADC Sample Sequence Control 3 */ __IO uint32_t SSFIFO3; /*!< ADC Sample Sequence Result FIFO 3 */ __IO uint32_t SSFSTAT3; /*!< ADC Sample Sequence FIFO 3 Status */ __IO uint32_t SSOP3; /*!< ADC Sample Sequence 3 Operation */ __IO uint32_t SSDC3; /*!< ADC Sample Sequence 3 Digital Comparator Select */ __I uint32_t RESERVED5[786]; __O uint32_t DCRIC; /*!< ADC Digital Comparator Reset Initial Conditions */ __I uint32_t RESERVED6[63]; __IO uint32_t DCCTL0; /*!< ADC Digital Comparator Control 0 */ __IO uint32_t DCCTL1; /*!< ADC Digital Comparator Control 1 */ __IO uint32_t DCCTL2; /*!< ADC Digital Comparator Control 2 */ __IO uint32_t DCCTL3; /*!< ADC Digital Comparator Control 3 */ __IO uint32_t DCCTL4; /*!< ADC Digital Comparator Control 4 */ __IO uint32_t DCCTL5; /*!< ADC Digital Comparator Control 5 */ __IO uint32_t DCCTL6; /*!< ADC Digital Comparator Control 6 */ __IO uint32_t DCCTL7; /*!< ADC Digital Comparator Control 7 */ __I uint32_t RESERVED7[8]; __IO uint32_t DCCMP0; /*!< ADC Digital Comparator Range 0 */ __IO uint32_t DCCMP1; /*!< ADC Digital Comparator Range 1 */ __IO uint32_t DCCMP2; /*!< ADC Digital Comparator Range 2 */ __IO uint32_t DCCMP3; /*!< ADC Digital Comparator Range 3 */ __IO uint32_t DCCMP4; /*!< ADC Digital Comparator Range 4 */ __IO uint32_t DCCMP5; /*!< ADC Digital Comparator Range 5 */ __IO uint32_t DCCMP6; /*!< ADC Digital Comparator Range 6 */ __IO uint32_t DCCMP7; /*!< ADC Digital Comparator Range 7 */ __I uint32_t RESERVED8[88]; __IO uint32_t PP; /*!< ADC Peripheral Properties */ __IO uint32_t PC; /*!< ADC Peripheral Configuration */ __IO uint32_t CC; /*!< ADC Clock Configuration */ } ADC0_Type; /* ================================================================================ */ /* ================ COMP ================ */ /* ================================================================================ */ /** * @brief Register map for COMP peripheral (COMP) */ typedef struct { /*!< COMP Structure */ __IO uint32_t ACMIS; /*!< Analog Comparator Masked Interrupt Status */ __IO uint32_t ACRIS; /*!< Analog Comparator Raw Interrupt Status */ __IO uint32_t ACINTEN; /*!< Analog Comparator Interrupt Enable */ __I uint32_t RESERVED0; __IO uint32_t ACREFCTL; /*!< Analog Comparator Reference Voltage Control */ __I uint32_t RESERVED1[3]; __IO uint32_t ACSTAT0; /*!< Analog Comparator Status 0 */ __IO uint32_t ACCTL0; /*!< Analog Comparator Control 0 */ __I uint32_t RESERVED2[6]; __IO uint32_t ACSTAT1; /*!< Analog Comparator Status 1 */ __IO uint32_t ACCTL1; /*!< Analog Comparator Control 1 */ __I uint32_t RESERVED3[990]; __IO uint32_t PP; /*!< Analog Comparator Peripheral Properties */ } COMP_Type; /* ================================================================================ */ /* ================ CAN0 ================ */ /* ================================================================================ */ /** * @brief Register map for CAN0 peripheral (CAN0) */ typedef struct { /*!< CAN0 Structure */ __IO uint32_t CTL; /*!< CAN Control */ __IO uint32_t STS; /*!< CAN Status */ __IO uint32_t ERR; /*!< CAN Error Counter */ __IO uint32_t BIT; /*!< CAN Bit Timing */ __IO uint32_t INT; /*!< CAN Interrupt */ __IO uint32_t TST; /*!< CAN Test */ __IO uint32_t BRPE; /*!< CAN Baud Rate Prescaler Extension */ __I uint32_t RESERVED0; __IO uint32_t IF1CRQ; /*!< CAN IF1 Command Request */ union { __IO uint32_t IF1CMSK_CAN0_ALT; /*!< CAN IF1 Command Mask */ __IO uint32_t IF1CMSK; /*!< CAN IF1 Command Mask */ }; __IO uint32_t IF1MSK1; /*!< CAN IF1 Mask 1 */ __IO uint32_t IF1MSK2; /*!< CAN IF1 Mask 2 */ __IO uint32_t IF1ARB1; /*!< CAN IF1 Arbitration 1 */ __IO uint32_t IF1ARB2; /*!< CAN IF1 Arbitration 2 */ __IO uint32_t IF1MCTL; /*!< CAN IF1 Message Control */ __IO uint32_t IF1DA1; /*!< CAN IF1 Data A1 */ __IO uint32_t IF1DA2; /*!< CAN IF1 Data A2 */ __IO uint32_t IF1DB1; /*!< CAN IF1 Data B1 */ __IO uint32_t IF1DB2; /*!< CAN IF1 Data B2 */ __I uint32_t RESERVED1[13]; __IO uint32_t IF2CRQ; /*!< CAN IF2 Command Request */ union { __IO uint32_t IF2CMSK_CAN0_ALT; /*!< CAN IF2 Command Mask */ __IO uint32_t IF2CMSK; /*!< CAN IF2 Command Mask */ }; __IO uint32_t IF2MSK1; /*!< CAN IF2 Mask 1 */ __IO uint32_t IF2MSK2; /*!< CAN IF2 Mask 2 */ __IO uint32_t IF2ARB1; /*!< CAN IF2 Arbitration 1 */ __IO uint32_t IF2ARB2; /*!< CAN IF2 Arbitration 2 */ __IO uint32_t IF2MCTL; /*!< CAN IF2 Message Control */ __IO uint32_t IF2DA1; /*!< CAN IF2 Data A1 */ __IO uint32_t IF2DA2; /*!< CAN IF2 Data A2 */ __IO uint32_t IF2DB1; /*!< CAN IF2 Data B1 */ __IO uint32_t IF2DB2; /*!< CAN IF2 Data B2 */ __I uint32_t RESERVED2[21]; __IO uint32_t TXRQ1; /*!< CAN Transmission Request 1 */ __IO uint32_t TXRQ2; /*!< CAN Transmission Request 2 */ __I uint32_t RESERVED3[6]; __IO uint32_t NWDA1; /*!< CAN New Data 1 */ __IO uint32_t NWDA2; /*!< CAN New Data 2 */ __I uint32_t RESERVED4[6]; __IO uint32_t MSG1INT; /*!< CAN Message 1 Interrupt Pending */ __IO uint32_t MSG2INT; /*!< CAN Message 2 Interrupt Pending */ __I uint32_t RESERVED5[6]; __IO uint32_t MSG1VAL; /*!< CAN Message 1 Valid */ __IO uint32_t MSG2VAL; /*!< CAN Message 2 Valid */ } CAN0_Type; /* ================================================================================ */ /* ================ USB0 ================ */ /* ================================================================================ */ /** * @brief Register map for USB0 peripheral (USB0) */ typedef struct { /*!< USB0 Structure */ __IO uint8_t FADDR; /*!< USB Device Functional Address */ __IO uint8_t POWER; /*!< USB Power */ __IO uint16_t TXIS; /*!< USB Transmit Interrupt Status */ __IO uint16_t RXIS; /*!< USB Receive Interrupt Status */ __IO uint16_t TXIE; /*!< USB Transmit Interrupt Enable */ __IO uint16_t RXIE; /*!< USB Receive Interrupt Enable */ union { __IO uint8_t IS_USB0_ALT; /*!< USB General Interrupt Status */ __IO uint8_t IS; /*!< USB General Interrupt Status */ }; union { __IO uint8_t IE_USB0_ALT; /*!< USB Interrupt Enable */ __IO uint8_t IE; /*!< USB Interrupt Enable */ }; __IO uint16_t FRAME; /*!< USB Frame Value */ __IO uint8_t EPIDX; /*!< USB Endpoint Index */ __IO uint8_t TEST; /*!< USB Test Mode */ __I uint32_t RESERVED0[4]; __IO uint32_t FIFO0; /*!< USB FIFO Endpoint 0 */ __IO uint32_t FIFO1; /*!< USB FIFO Endpoint 1 */ __IO uint32_t FIFO2; /*!< USB FIFO Endpoint 2 */ __IO uint32_t FIFO3; /*!< USB FIFO Endpoint 3 */ __IO uint32_t FIFO4; /*!< USB FIFO Endpoint 4 */ __IO uint32_t FIFO5; /*!< USB FIFO Endpoint 5 */ __IO uint32_t FIFO6; /*!< USB FIFO Endpoint 6 */ __IO uint32_t FIFO7; /*!< USB FIFO Endpoint 7 */ __I uint32_t RESERVED1[8]; __IO uint8_t DEVCTL; /*!< USB Device Control */ __I uint8_t RESERVED2[1]; __IO uint8_t TXFIFOSZ; /*!< USB Transmit Dynamic FIFO Sizing */ __IO uint8_t RXFIFOSZ; /*!< USB Receive Dynamic FIFO Sizing */ __IO uint16_t TXFIFOADD; /*!< USB Transmit FIFO Start Address */ __IO uint16_t RXFIFOADD; /*!< USB Receive FIFO Start Address */ __I uint32_t RESERVED3[4]; __I uint16_t RESERVED4; __IO uint8_t CONTIM; /*!< USB Connect Timing */ __IO uint8_t VPLEN; /*!< USB OTG VBUS Pulse Timing */ __I uint8_t RESERVED5[1]; __IO uint8_t FSEOF; /*!< USB Full-Speed Last Transaction to End of Frame Timing */ __IO uint8_t LSEOF; /*!< USB Low-Speed Last Transaction to End of Frame Timing */ __I uint8_t RESERVED6[1]; __IO uint8_t TXFUNCADDR0; /*!< USB Transmit Functional Address Endpoint 0 */ __I uint8_t RESERVED7[1]; __IO uint8_t TXHUBADDR0; /*!< USB Transmit Hub Address Endpoint 0 */ __IO uint8_t TXHUBPORT0; /*!< USB Transmit Hub Port Endpoint 0 */ __I uint32_t RESERVED8; __IO uint8_t TXFUNCADDR1; /*!< USB Transmit Functional Address Endpoint 1 */ __I uint8_t RESERVED9[1]; __IO uint8_t TXHUBADDR1; /*!< USB Transmit Hub Address Endpoint 1 */ __IO uint8_t TXHUBPORT1; /*!< USB Transmit Hub Port Endpoint 1 */ __IO uint8_t RXFUNCADDR1; /*!< USB Receive Functional Address Endpoint 1 */ __I uint8_t RESERVED10[1]; __IO uint8_t RXHUBADDR1; /*!< USB Receive Hub Address Endpoint 1 */ __IO uint8_t RXHUBPORT1; /*!< USB Receive Hub Port Endpoint 1 */ __IO uint8_t TXFUNCADDR2; /*!< USB Transmit Functional Address Endpoint 2 */ __I uint8_t RESERVED11[1]; __IO uint8_t TXHUBADDR2; /*!< USB Transmit Hub Address Endpoint 2 */ __IO uint8_t TXHUBPORT2; /*!< USB Transmit Hub Port Endpoint 2 */ __IO uint8_t RXFUNCADDR2; /*!< USB Receive Functional Address Endpoint 2 */ __I uint8_t RESERVED12[1]; __IO uint8_t RXHUBADDR2; /*!< USB Receive Hub Address Endpoint 2 */ __IO uint8_t RXHUBPORT2; /*!< USB Receive Hub Port Endpoint 2 */ __IO uint8_t TXFUNCADDR3; /*!< USB Transmit Functional Address Endpoint 3 */ __I uint8_t RESERVED13[1]; __IO uint8_t TXHUBADDR3; /*!< USB Transmit Hub Address Endpoint 3 */ __IO uint8_t TXHUBPORT3; /*!< USB Transmit Hub Port Endpoint 3 */ __IO uint8_t RXFUNCADDR3; /*!< USB Receive Functional Address Endpoint 3 */ __I uint8_t RESERVED14[1]; __IO uint8_t RXHUBADDR3; /*!< USB Receive Hub Address Endpoint 3 */ __IO uint8_t RXHUBPORT3; /*!< USB Receive Hub Port Endpoint 3 */ __IO uint8_t TXFUNCADDR4; /*!< USB Transmit Functional Address Endpoint 4 */ __I uint8_t RESERVED15[1]; __IO uint8_t TXHUBADDR4; /*!< USB Transmit Hub Address Endpoint 4 */ __IO uint8_t TXHUBPORT4; /*!< USB Transmit Hub Port Endpoint 4 */ __IO uint8_t RXFUNCADDR4; /*!< USB Receive Functional Address Endpoint 4 */ __I uint8_t RESERVED16[1]; __IO uint8_t RXHUBADDR4; /*!< USB Receive Hub Address Endpoint 4 */ __IO uint8_t RXHUBPORT4; /*!< USB Receive Hub Port Endpoint 4 */ __IO uint8_t TXFUNCADDR5; /*!< USB Transmit Functional Address Endpoint 5 */ __I uint8_t RESERVED17[1]; __IO uint8_t TXHUBADDR5; /*!< USB Transmit Hub Address Endpoint 5 */ __IO uint8_t TXHUBPORT5; /*!< USB Transmit Hub Port Endpoint 5 */ __IO uint8_t RXFUNCADDR5; /*!< USB Receive Functional Address Endpoint 5 */ __I uint8_t RESERVED18[1]; __IO uint8_t RXHUBADDR5; /*!< USB Receive Hub Address Endpoint 5 */ __IO uint8_t RXHUBPORT5; /*!< USB Receive Hub Port Endpoint 5 */ __IO uint8_t TXFUNCADDR6; /*!< USB Transmit Functional Address Endpoint 6 */ __I uint8_t RESERVED19[1]; __IO uint8_t TXHUBADDR6; /*!< USB Transmit Hub Address Endpoint 6 */ __IO uint8_t TXHUBPORT6; /*!< USB Transmit Hub Port Endpoint 6 */ __IO uint8_t RXFUNCADDR6; /*!< USB Receive Functional Address Endpoint 6 */ __I uint8_t RESERVED20[1]; __IO uint8_t RXHUBADDR6; /*!< USB Receive Hub Address Endpoint 6 */ __IO uint8_t RXHUBPORT6; /*!< USB Receive Hub Port Endpoint 6 */ __IO uint8_t TXFUNCADDR7; /*!< USB Transmit Functional Address Endpoint 7 */ __I uint8_t RESERVED21[1]; __IO uint8_t TXHUBADDR7; /*!< USB Transmit Hub Address Endpoint 7 */ __IO uint8_t TXHUBPORT7; /*!< USB Transmit Hub Port Endpoint 7 */ __IO uint8_t RXFUNCADDR7; /*!< USB Receive Functional Address Endpoint 7 */ __I uint8_t RESERVED22[1]; __IO uint8_t RXHUBADDR7; /*!< USB Receive Hub Address Endpoint 7 */ __IO uint8_t RXHUBPORT7; /*!< USB Receive Hub Port Endpoint 7 */ __I uint32_t RESERVED23[16]; __I uint16_t RESERVED24; union { __O uint8_t CSRL0_USB0_ALT; /*!< USB Control and Status Endpoint 0 Low */ __O uint8_t CSRL0; /*!< USB Control and Status Endpoint 0 Low */ }; __O uint8_t CSRH0; /*!< USB Control and Status Endpoint 0 High */ __I uint16_t RESERVED25[3]; __IO uint8_t COUNT0; /*!< USB Receive Byte Count Endpoint 0 */ __I uint8_t RESERVED26[1]; __IO uint8_t TYPE0; /*!< USB Type Endpoint 0 */ __IO uint8_t NAKLMT; /*!< USB NAK Limit */ __I uint32_t RESERVED27; __IO uint16_t TXMAXP1; /*!< USB Maximum Transmit Data Endpoint 1 */ union { __IO uint8_t TXCSRL1_USB0_ALT; /*!< USB Transmit Control and Status Endpoint 1 Low */ __IO uint8_t TXCSRL1; /*!< USB Transmit Control and Status Endpoint 1 Low */ }; __IO uint8_t TXCSRH1; /*!< USB Transmit Control and Status Endpoint 1 High */ __IO uint16_t RXMAXP1; /*!< USB Maximum Receive Data Endpoint 1 */ union { __IO uint8_t RXCSRL1_USB0_ALT; /*!< USB Receive Control and Status Endpoint 1 Low */ __IO uint8_t RXCSRL1; /*!< USB Receive Control and Status Endpoint 1 Low */ }; union { __IO uint8_t RXCSRH1_USB0_ALT; /*!< USB Receive Control and Status Endpoint 1 High */ __IO uint8_t RXCSRH1; /*!< USB Receive Control and Status Endpoint 1 High */ }; __IO uint16_t RXCOUNT1; /*!< USB Receive Byte Count Endpoint 1 */ __IO uint8_t TXTYPE1; /*!< USB Host Transmit Configure Type Endpoint 1 */ union { __IO uint8_t TXINTERVAL1_USB0_ALT; /*!< USB Host Transmit Interval Endpoint 1 */ __IO uint8_t TXINTERVAL1; /*!< USB Host Transmit Interval Endpoint 1 */ }; __IO uint8_t RXTYPE1; /*!< USB Host Configure Receive Type Endpoint 1 */ union { __IO uint8_t RXINTERVAL1_USB0_ALT; /*!< USB Host Receive Polling Interval Endpoint 1 */ __IO uint8_t RXINTERVAL1; /*!< USB Host Receive Polling Interval Endpoint 1 */ }; __I uint16_t RESERVED28; __IO uint16_t TXMAXP2; /*!< USB Maximum Transmit Data Endpoint 2 */ union { __IO uint8_t TXCSRL2_USB0_ALT; /*!< USB Transmit Control and Status Endpoint 2 Low */ __IO uint8_t TXCSRL2; /*!< USB Transmit Control and Status Endpoint 2 Low */ }; __IO uint8_t TXCSRH2; /*!< USB Transmit Control and Status Endpoint 2 High */ __IO uint16_t RXMAXP2; /*!< USB Maximum Receive Data Endpoint 2 */ union { __IO uint8_t RXCSRL2_USB0_ALT; /*!< USB Receive Control and Status Endpoint 2 Low */ __IO uint8_t RXCSRL2; /*!< USB Receive Control and Status Endpoint 2 Low */ }; union { __IO uint8_t RXCSRH2_USB0_ALT; /*!< USB Receive Control and Status Endpoint 2 High */ __IO uint8_t RXCSRH2; /*!< USB Receive Control and Status Endpoint 2 High */ }; __IO uint16_t RXCOUNT2; /*!< USB Receive Byte Count Endpoint 2 */ __IO uint8_t TXTYPE2; /*!< USB Host Transmit Configure Type Endpoint 2 */ union { __IO uint8_t TXINTERVAL2_USB0_ALT; /*!< USB Host Transmit Interval Endpoint 2 */ __IO uint8_t TXINTERVAL2; /*!< USB Host Transmit Interval Endpoint 2 */ }; __IO uint8_t RXTYPE2; /*!< USB Host Configure Receive Type Endpoint 2 */ union { __IO uint8_t RXINTERVAL2_USB0_ALT; /*!< USB Host Receive Polling Interval Endpoint 2 */ __IO uint8_t RXINTERVAL2; /*!< USB Host Receive Polling Interval Endpoint 2 */ }; __I uint16_t RESERVED29; __IO uint16_t TXMAXP3; /*!< USB Maximum Transmit Data Endpoint 3 */ union { __IO uint8_t TXCSRL3_USB0_ALT; /*!< USB Transmit Control and Status Endpoint 3 Low */ __IO uint8_t TXCSRL3; /*!< USB Transmit Control and Status Endpoint 3 Low */ }; __IO uint8_t TXCSRH3; /*!< USB Transmit Control and Status Endpoint 3 High */ __IO uint16_t RXMAXP3; /*!< USB Maximum Receive Data Endpoint 3 */ union { __IO uint8_t RXCSRL3_USB0_ALT; /*!< USB Receive Control and Status Endpoint 3 Low */ __IO uint8_t RXCSRL3; /*!< USB Receive Control and Status Endpoint 3 Low */ }; union { __IO uint8_t RXCSRH3_USB0_ALT; /*!< USB Receive Control and Status Endpoint 3 High */ __IO uint8_t RXCSRH3; /*!< USB Receive Control and Status Endpoint 3 High */ }; __IO uint16_t RXCOUNT3; /*!< USB Receive Byte Count Endpoint 3 */ __IO uint8_t TXTYPE3; /*!< USB Host Transmit Configure Type Endpoint 3 */ union { __IO uint8_t TXINTERVAL3_USB0_ALT; /*!< USB Host Transmit Interval Endpoint 3 */ __IO uint8_t TXINTERVAL3; /*!< USB Host Transmit Interval Endpoint 3 */ }; __IO uint8_t RXTYPE3; /*!< USB Host Configure Receive Type Endpoint 3 */ union { __IO uint8_t RXINTERVAL3_USB0_ALT; /*!< USB Host Receive Polling Interval Endpoint 3 */ __IO uint8_t RXINTERVAL3; /*!< USB Host Receive Polling Interval Endpoint 3 */ }; __I uint16_t RESERVED30; __IO uint16_t TXMAXP4; /*!< USB Maximum Transmit Data Endpoint 4 */ union { __IO uint8_t TXCSRL4_USB0_ALT; /*!< USB Transmit Control and Status Endpoint 4 Low */ __IO uint8_t TXCSRL4; /*!< USB Transmit Control and Status Endpoint 4 Low */ }; __IO uint8_t TXCSRH4; /*!< USB Transmit Control and Status Endpoint 4 High */ __IO uint16_t RXMAXP4; /*!< USB Maximum Receive Data Endpoint 4 */ union { __IO uint8_t RXCSRL4_USB0_ALT; /*!< USB Receive Control and Status Endpoint 4 Low */ __IO uint8_t RXCSRL4; /*!< USB Receive Control and Status Endpoint 4 Low */ }; union { __IO uint8_t RXCSRH4_USB0_ALT; /*!< USB Receive Control and Status Endpoint 4 High */ __IO uint8_t RXCSRH4; /*!< USB Receive Control and Status Endpoint 4 High */ }; __IO uint16_t RXCOUNT4; /*!< USB Receive Byte Count Endpoint 4 */ __IO uint8_t TXTYPE4; /*!< USB Host Transmit Configure Type Endpoint 4 */ union { __IO uint8_t TXINTERVAL4_USB0_ALT; /*!< USB Host Transmit Interval Endpoint 4 */ __IO uint8_t TXINTERVAL4; /*!< USB Host Transmit Interval Endpoint 4 */ }; __IO uint8_t RXTYPE4; /*!< USB Host Configure Receive Type Endpoint 4 */ union { __IO uint8_t RXINTERVAL4_USB0_ALT; /*!< USB Host Receive Polling Interval Endpoint 4 */ __IO uint8_t RXINTERVAL4; /*!< USB Host Receive Polling Interval Endpoint 4 */ }; __I uint16_t RESERVED31; __IO uint16_t TXMAXP5; /*!< USB Maximum Transmit Data Endpoint 5 */ union { __IO uint8_t TXCSRL5_USB0_ALT; /*!< USB Transmit Control and Status Endpoint 5 Low */ __IO uint8_t TXCSRL5; /*!< USB Transmit Control and Status Endpoint 5 Low */ }; __IO uint8_t TXCSRH5; /*!< USB Transmit Control and Status Endpoint 5 High */ __IO uint16_t RXMAXP5; /*!< USB Maximum Receive Data Endpoint 5 */ union { __IO uint8_t RXCSRL5_USB0_ALT; /*!< USB Receive Control and Status Endpoint 5 Low */ __IO uint8_t RXCSRL5; /*!< USB Receive Control and Status Endpoint 5 Low */ }; union { __IO uint8_t RXCSRH5_USB0_ALT; /*!< USB Receive Control and Status Endpoint 5 High */ __IO uint8_t RXCSRH5; /*!< USB Receive Control and Status Endpoint 5 High */ }; __IO uint16_t RXCOUNT5; /*!< USB Receive Byte Count Endpoint 5 */ __IO uint8_t TXTYPE5; /*!< USB Host Transmit Configure Type Endpoint 5 */ union { __IO uint8_t TXINTERVAL5_USB0_ALT; /*!< USB Host Transmit Interval Endpoint 5 */ __IO uint8_t TXINTERVAL5; /*!< USB Host Transmit Interval Endpoint 5 */ }; __IO uint8_t RXTYPE5; /*!< USB Host Configure Receive Type Endpoint 5 */ union { __IO uint8_t RXINTERVAL5_USB0_ALT; /*!< USB Host Receive Polling Interval Endpoint 5 */ __IO uint8_t RXINTERVAL5; /*!< USB Host Receive Polling Interval Endpoint 5 */ }; __I uint16_t RESERVED32; __IO uint16_t TXMAXP6; /*!< USB Maximum Transmit Data Endpoint 6 */ union { __IO uint8_t TXCSRL6_USB0_ALT; /*!< USB Transmit Control and Status Endpoint 6 Low */ __IO uint8_t TXCSRL6; /*!< USB Transmit Control and Status Endpoint 6 Low */ }; __IO uint8_t TXCSRH6; /*!< USB Transmit Control and Status Endpoint 6 High */ __IO uint16_t RXMAXP6; /*!< USB Maximum Receive Data Endpoint 6 */ union { __IO uint8_t RXCSRL6_USB0_ALT; /*!< USB Receive Control and Status Endpoint 6 Low */ __IO uint8_t RXCSRL6; /*!< USB Receive Control and Status Endpoint 6 Low */ }; union { __IO uint8_t RXCSRH6_USB0_ALT; /*!< USB Receive Control and Status Endpoint 6 High */ __IO uint8_t RXCSRH6; /*!< USB Receive Control and Status Endpoint 6 High */ }; __IO uint16_t RXCOUNT6; /*!< USB Receive Byte Count Endpoint 6 */ __IO uint8_t TXTYPE6; /*!< USB Host Transmit Configure Type Endpoint 6 */ union { __IO uint8_t TXINTERVAL6_USB0_ALT; /*!< USB Host Transmit Interval Endpoint 6 */ __IO uint8_t TXINTERVAL6; /*!< USB Host Transmit Interval Endpoint 6 */ }; __IO uint8_t RXTYPE6; /*!< USB Host Configure Receive Type Endpoint 6 */ union { __IO uint8_t RXINTERVAL6_USB0_ALT; /*!< USB Host Receive Polling Interval Endpoint 6 */ __IO uint8_t RXINTERVAL6; /*!< USB Host Receive Polling Interval Endpoint 6 */ }; __I uint16_t RESERVED33; __IO uint16_t TXMAXP7; /*!< USB Maximum Transmit Data Endpoint 7 */ union { __IO uint8_t TXCSRL7_USB0_ALT; /*!< USB Transmit Control and Status Endpoint 7 Low */ __IO uint8_t TXCSRL7; /*!< USB Transmit Control and Status Endpoint 7 Low */ }; __IO uint8_t TXCSRH7; /*!< USB Transmit Control and Status Endpoint 7 High */ __IO uint16_t RXMAXP7; /*!< USB Maximum Receive Data Endpoint 7 */ union { __IO uint8_t RXCSRL7_USB0_ALT; /*!< USB Receive Control and Status Endpoint 7 Low */ __IO uint8_t RXCSRL7; /*!< USB Receive Control and Status Endpoint 7 Low */ }; union { __IO uint8_t RXCSRH7_USB0_ALT; /*!< USB Receive Control and Status Endpoint 7 High */ __IO uint8_t RXCSRH7; /*!< USB Receive Control and Status Endpoint 7 High */ }; __IO uint16_t RXCOUNT7; /*!< USB Receive Byte Count Endpoint 7 */ __IO uint8_t TXTYPE7; /*!< USB Host Transmit Configure Type Endpoint 7 */ union { __IO uint8_t TXINTERVAL7_USB0_ALT; /*!< USB Host Transmit Interval Endpoint 7 */ __IO uint8_t TXINTERVAL7; /*!< USB Host Transmit Interval Endpoint 7 */ }; __IO uint8_t RXTYPE7; /*!< USB Host Configure Receive Type Endpoint 7 */ union { __IO uint8_t RXINTERVAL7_USB0_ALT; /*!< USB Host Receive Polling Interval Endpoint 7 */ __IO uint8_t RXINTERVAL7; /*!< USB Host Receive Polling Interval Endpoint 7 */ }; __I uint16_t RESERVED34[195]; __IO uint16_t RQPKTCOUNT1; /*!< USB Request Packet Count in Block Transfer Endpoint 1 */ __I uint16_t RESERVED35; __IO uint16_t RQPKTCOUNT2; /*!< USB Request Packet Count in Block Transfer Endpoint 2 */ __I uint16_t RESERVED36; __IO uint16_t RQPKTCOUNT3; /*!< USB Request Packet Count in Block Transfer Endpoint 3 */ __I uint16_t RESERVED37; __IO uint16_t RQPKTCOUNT4; /*!< USB Request Packet Count in Block Transfer Endpoint 4 */ __I uint16_t RESERVED38; __IO uint16_t RQPKTCOUNT5; /*!< USB Request Packet Count in Block Transfer Endpoint 5 */ __I uint16_t RESERVED39; __IO uint16_t RQPKTCOUNT6; /*!< USB Request Packet Count in Block Transfer Endpoint 6 */ __I uint16_t RESERVED40; __IO uint16_t RQPKTCOUNT7; /*!< USB Request Packet Count in Block Transfer Endpoint 7 */ __I uint16_t RESERVED41[17]; __IO uint16_t RXDPKTBUFDIS; /*!< USB Receive Double Packet Buffer Disable */ __IO uint16_t TXDPKTBUFDIS; /*!< USB Transmit Double Packet Buffer Disable */ __I uint32_t RESERVED42[47]; __IO uint32_t EPC; /*!< USB External Power Control */ __IO uint32_t EPCRIS; /*!< USB External Power Control Raw Interrupt Status */ __IO uint32_t EPCIM; /*!< USB External Power Control Interrupt Mask */ __IO uint32_t EPCISC; /*!< USB External Power Control Interrupt Status and Clear */ __IO uint32_t DRRIS; /*!< USB Device RESUME Raw Interrupt Status */ __IO uint32_t DRIM; /*!< USB Device RESUME Interrupt Mask */ __O uint32_t DRISC; /*!< USB Device RESUME Interrupt Status and Clear */ __IO uint32_t GPCS; /*!< USB General-Purpose Control and Status */ __I uint32_t RESERVED43[4]; __IO uint32_t VDC; /*!< USB VBUS Droop Control */ __IO uint32_t VDCRIS; /*!< USB VBUS Droop Control Raw Interrupt Status */ __IO uint32_t VDCIM; /*!< USB VBUS Droop Control Interrupt Mask */ __IO uint32_t VDCISC; /*!< USB VBUS Droop Control Interrupt Status and Clear */ __I uint32_t RESERVED44; __IO uint32_t IDVRIS; /*!< USB ID Valid Detect Raw Interrupt Status */ __IO uint32_t IDVIM; /*!< USB ID Valid Detect Interrupt Mask */ __IO uint32_t IDVISC; /*!< USB ID Valid Detect Interrupt Status and Clear */ __IO uint32_t DMASEL; /*!< USB DMA Select */ __I uint32_t RESERVED45[731]; __IO uint32_t PP; /*!< USB Peripheral Properties */ } USB0_Type; /* ================================================================================ */ /* ================ EEPROM ================ */ /* ================================================================================ */ /** * @brief Register map for EEPROM peripheral (EEPROM) */ typedef struct { /*!< EEPROM Structure */ __IO uint32_t EESIZE; /*!< EEPROM Size Information */ __IO uint32_t EEBLOCK; /*!< EEPROM Current Block */ __IO uint32_t EEOFFSET; /*!< EEPROM Current Offset */ __I uint32_t RESERVED0; __IO uint32_t EERDWR; /*!< EEPROM Read-Write */ __IO uint32_t EERDWRINC; /*!< EEPROM Read-Write with Increment */ __IO uint32_t EEDONE; /*!< EEPROM Done Status */ __IO uint32_t EESUPP; /*!< EEPROM Support Control and Status */ __IO uint32_t EEUNLOCK; /*!< EEPROM Unlock */ __I uint32_t RESERVED1[3]; __IO uint32_t EEPROT; /*!< EEPROM Protection */ __IO uint32_t EEPASS0; /*!< EEPROM Password */ __IO uint32_t EEPASS1; /*!< EEPROM Password */ __IO uint32_t EEPASS2; /*!< EEPROM Password */ __IO uint32_t EEINT; /*!< EEPROM Interrupt */ __I uint32_t RESERVED2[3]; __IO uint32_t EEHIDE; /*!< EEPROM Block Hide */ __I uint32_t RESERVED3[11]; __IO uint32_t EEDBGME; /*!< EEPROM Debug Mass Erase */ __I uint32_t RESERVED4[975]; __IO uint32_t PP; /*!< EEPROM Peripheral Properties */ } EEPROM_Type; /* ================================================================================ */ /* ================ SYSEXC ================ */ /* ================================================================================ */ /** * @brief Register map for SYSEXC peripheral (SYSEXC) */ typedef struct { /*!< SYSEXC Structure */ __IO uint32_t RIS; /*!< System Exception Raw Interrupt Status */ __IO uint32_t IM; /*!< System Exception Interrupt Mask */ __IO uint32_t MIS; /*!< System Exception Masked Interrupt Status */ __O uint32_t IC; /*!< System Exception Interrupt Clear */ } SYSEXC_Type; /* ================================================================================ */ /* ================ HIB ================ */ /* ================================================================================ */ /** * @brief Register map for HIB peripheral (HIB) */ typedef struct { /*!< HIB Structure */ __IO uint32_t RTCC; /*!< Hibernation RTC Counter */ __IO uint32_t RTCM0; /*!< Hibernation RTC Match 0 */ __I uint32_t RESERVED0; __IO uint32_t RTCLD; /*!< Hibernation RTC Load */ __IO uint32_t CTL; /*!< Hibernation Control */ __IO uint32_t IM; /*!< Hibernation Interrupt Mask */ __IO uint32_t RIS; /*!< Hibernation Raw Interrupt Status */ __IO uint32_t MIS; /*!< Hibernation Masked Interrupt Status */ __IO uint32_t IC; /*!< Hibernation Interrupt Clear */ __IO uint32_t RTCT; /*!< Hibernation RTC Trim */ __IO uint32_t RTCSS; /*!< Hibernation RTC Sub Seconds */ __I uint32_t RESERVED1; __IO uint32_t DATA; /*!< Hibernation Data */ } HIB_Type; /* ================================================================================ */ /* ================ FLASH_CTRL ================ */ /* ================================================================================ */ /** * @brief Register map for FLASH_CTRL peripheral (FLASH_CTRL) */ typedef struct { /*!< FLASH_CTRL Structure */ __IO uint32_t FMA; /*!< Flash Memory Address */ __IO uint32_t FMD; /*!< Flash Memory Data */ __IO uint32_t FMC; /*!< Flash Memory Control */ __IO uint32_t FCRIS; /*!< Flash Controller Raw Interrupt Status */ __IO uint32_t FCIM; /*!< Flash Controller Interrupt Mask */ __IO uint32_t FCMISC; /*!< Flash Controller Masked Interrupt Status and Clear */ __I uint32_t RESERVED0[2]; __IO uint32_t FMC2; /*!< Flash Memory Control 2 */ __I uint32_t RESERVED1[3]; __IO uint32_t FWBVAL; /*!< Flash Write Buffer Valid */ __I uint32_t RESERVED2[51]; __IO uint32_t FWBN; /*!< Flash Write Buffer n */ __I uint32_t RESERVED3[943]; __IO uint32_t FSIZE; /*!< Flash Size */ __IO uint32_t SSIZE; /*!< SRAM Size */ __I uint32_t RESERVED4; union { __IO uint32_t ROMSWMAP_FLASH_CTRL_ALT; /*!< ROM Software Map */ __IO uint32_t ROMSWMAP; /*!< ROM Software Map */ }; __I uint32_t RESERVED5[72]; __IO uint32_t RMCTL; /*!< ROM Control */ __I uint32_t RESERVED6[55]; __IO uint32_t BOOTCFG; /*!< Boot Configuration */ __I uint32_t RESERVED7[3]; __IO uint32_t USERREG0; /*!< User Register 0 */ __IO uint32_t USERREG1; /*!< User Register 1 */ __IO uint32_t USERREG2; /*!< User Register 2 */ __IO uint32_t USERREG3; /*!< User Register 3 */ __I uint32_t RESERVED8[4]; __IO uint32_t FMPRE0; /*!< Flash Memory Protection Read Enable 0 */ __IO uint32_t FMPRE1; /*!< Flash Memory Protection Read Enable 1 */ __IO uint32_t FMPRE2; /*!< Flash Memory Protection Read Enable 2 */ __IO uint32_t FMPRE3; /*!< Flash Memory Protection Read Enable 3 */ __I uint32_t RESERVED9[124]; __IO uint32_t FMPPE0; /*!< Flash Memory Protection Program Enable 0 */ __IO uint32_t FMPPE1; /*!< Flash Memory Protection Program Enable 1 */ __IO uint32_t FMPPE2; /*!< Flash Memory Protection Program Enable 2 */ __IO uint32_t FMPPE3; /*!< Flash Memory Protection Program Enable 3 */ } FLASH_CTRL_Type; /* ================================================================================ */ /* ================ SYSCTL ================ */ /* ================================================================================ */ /** * @brief Register map for SYSCTL peripheral (SYSCTL) */ typedef struct { /*!< SYSCTL Structure */ __IO uint32_t DID0; /*!< Device Identification 0 */ __IO uint32_t DID1; /*!< Device Identification 1 */ __IO uint32_t DC0; /*!< Device Capabilities 0 */ __I uint32_t RESERVED0; __IO uint32_t DC1; /*!< Device Capabilities 1 */ __IO uint32_t DC2; /*!< Device Capabilities 2 */ __IO uint32_t DC3; /*!< Device Capabilities 3 */ __IO uint32_t DC4; /*!< Device Capabilities 4 */ __IO uint32_t DC5; /*!< Device Capabilities 5 */ __IO uint32_t DC6; /*!< Device Capabilities 6 */ __IO uint32_t DC7; /*!< Device Capabilities 7 */ __IO uint32_t DC8; /*!< Device Capabilities 8 */ __IO uint32_t PBORCTL; /*!< Brown-Out Reset Control */ __I uint32_t RESERVED1[3]; __IO uint32_t SRCR0; /*!< Software Reset Control 0 */ __IO uint32_t SRCR1; /*!< Software Reset Control 1 */ __IO uint32_t SRCR2; /*!< Software Reset Control 2 */ __I uint32_t RESERVED2; __IO uint32_t RIS; /*!< Raw Interrupt Status */ __IO uint32_t IMC; /*!< Interrupt Mask Control */ __IO uint32_t MISC; /*!< Masked Interrupt Status and Clear */ __IO uint32_t RESC; /*!< Reset Cause */ __IO uint32_t RCC; /*!< Run-Mode Clock Configuration */ __I uint32_t RESERVED3[2]; __IO uint32_t GPIOHBCTL; /*!< GPIO High-Performance Bus Control */ __IO uint32_t RCC2; /*!< Run-Mode Clock Configuration 2 */ __I uint32_t RESERVED4[2]; __IO uint32_t MOSCCTL; /*!< Main Oscillator Control */ __I uint32_t RESERVED5[32]; __IO uint32_t RCGC0; /*!< Run Mode Clock Gating Control Register 0 */ __IO uint32_t RCGC1; /*!< Run Mode Clock Gating Control Register 1 */ __IO uint32_t RCGC2; /*!< Run Mode Clock Gating Control Register 2 */ __I uint32_t RESERVED6; __IO uint32_t SCGC0; /*!< Sleep Mode Clock Gating Control Register 0 */ __IO uint32_t SCGC1; /*!< Sleep Mode Clock Gating Control Register 1 */ __IO uint32_t SCGC2; /*!< Sleep Mode Clock Gating Control Register 2 */ __I uint32_t RESERVED7; __IO uint32_t DCGC0; /*!< Deep Sleep Mode Clock Gating Control Register 0 */ __IO uint32_t DCGC1; /*!< Deep-Sleep Mode Clock Gating Control Register 1 */ __IO uint32_t DCGC2; /*!< Deep Sleep Mode Clock Gating Control Register 2 */ __I uint32_t RESERVED8[6]; __IO uint32_t DSLPCLKCFG; /*!< Deep Sleep Clock Configuration */ __I uint32_t RESERVED9; __IO uint32_t SYSPROP; /*!< System Properties */ __IO uint32_t PIOSCCAL; /*!< Precision Internal Oscillator Calibration */ __IO uint32_t PIOSCSTAT; /*!< Precision Internal Oscillator Statistics */ __I uint32_t RESERVED10[2]; __IO uint32_t PLLFREQ0; /*!< PLL Frequency 0 */ __IO uint32_t PLLFREQ1; /*!< PLL Frequency 1 */ __IO uint32_t PLLSTAT; /*!< PLL Status */ __I uint32_t RESERVED11[7]; __IO uint32_t SLPPWRCFG; /*!< Sleep Power Configuration */ __IO uint32_t DSLPPWRCFG; /*!< Deep-Sleep Power Configuration */ __IO uint32_t DC9; /*!< Device Capabilities 9 */ __I uint32_t RESERVED12[3]; __IO uint32_t NVMSTAT; /*!< Non-Volatile Memory Information */ __I uint32_t RESERVED13[4]; __IO uint32_t LDOSPCTL; /*!< LDO Sleep Power Control */ __I uint32_t RESERVED14; __IO uint32_t LDODPCTL; /*!< LDO Deep-Sleep Power Control */ __I uint32_t RESERVED15[80]; __IO uint32_t PPWD; /*!< Watchdog Timer Peripheral Present */ __IO uint32_t PPTIMER; /*!< 16/32-Bit General-Purpose Timer Peripheral Present */ __IO uint32_t PPGPIO; /*!< General-Purpose Input/Output Peripheral Present */ __IO uint32_t PPDMA; /*!< Micro Direct Memory Access Peripheral Present */ __I uint32_t RESERVED16; __IO uint32_t PPHIB; /*!< Hibernation Peripheral Present */ __IO uint32_t PPUART; /*!< Universal Asynchronous Receiver/Transmitter Peripheral Present */ __IO uint32_t PPSSI; /*!< Synchronous Serial Interface Peripheral Present */ __IO uint32_t PPI2C; /*!< Inter-Integrated Circuit Peripheral Present */ __I uint32_t RESERVED17; __IO uint32_t PPUSB; /*!< Universal Serial Bus Peripheral Present */ __I uint32_t RESERVED18[2]; __IO uint32_t PPCAN; /*!< Controller Area Network Peripheral Present */ __IO uint32_t PPADC; /*!< Analog-to-Digital Converter Peripheral Present */ __IO uint32_t PPACMP; /*!< Analog Comparator Peripheral Present */ __IO uint32_t PPPWM; /*!< Pulse Width Modulator Peripheral Present */ __IO uint32_t PPQEI; /*!< Quadrature Encoder Interface Peripheral Present */ __I uint32_t RESERVED19[4]; __IO uint32_t PPEEPROM; /*!< EEPROM Peripheral Present */ __IO uint32_t PPWTIMER; /*!< 32/64-Bit Wide General-Purpose Timer Peripheral Present */ __I uint32_t RESERVED20[104]; __IO uint32_t SRWD; /*!< Watchdog Timer Software Reset */ __IO uint32_t SRTIMER; /*!< 16/32-Bit General-Purpose Timer Software Reset */ __IO uint32_t SRGPIO; /*!< General-Purpose Input/Output Software Reset */ __IO uint32_t SRDMA; /*!< Micro Direct Memory Access Software Reset */ __I uint32_t RESERVED21; __IO uint32_t SRHIB; /*!< Hibernation Software Reset */ __IO uint32_t SRUART; /*!< Universal Asynchronous Receiver/Transmitter Software Reset */ __IO uint32_t SRSSI; /*!< Synchronous Serial Interface Software Reset */ __IO uint32_t SRI2C; /*!< Inter-Integrated Circuit Software Reset */ __I uint32_t RESERVED22; __IO uint32_t SRUSB; /*!< Universal Serial Bus Software Reset */ __I uint32_t RESERVED23[2]; __IO uint32_t SRCAN; /*!< Controller Area Network Software Reset */ __IO uint32_t SRADC; /*!< Analog-to-Digital Converter Software Reset */ __IO uint32_t SRACMP; /*!< Analog Comparator Software Reset */ __IO uint32_t SRPWM; /*!< Pulse Width Modulator Software Reset */ __IO uint32_t SRQEI; /*!< Quadrature Encoder Interface Software Reset */ __I uint32_t RESERVED24[4]; __IO uint32_t SREEPROM; /*!< EEPROM Software Reset */ __IO uint32_t SRWTIMER; /*!< 32/64-Bit Wide General-Purpose Timer Software Reset */ __I uint32_t RESERVED25[40]; __IO uint32_t RCGCWD; /*!< Watchdog Timer Run Mode Clock Gating Control */ __IO uint32_t RCGCTIMER; /*!< 16/32-Bit General-Purpose Timer Run Mode Clock Gating Control */ __IO uint32_t RCGCGPIO; /*!< General-Purpose Input/Output Run Mode Clock Gating Control */ __IO uint32_t RCGCDMA; /*!< Micro Direct Memory Access Run Mode Clock Gating Control */ __I uint32_t RESERVED26; __IO uint32_t RCGCHIB; /*!< Hibernation Run Mode Clock Gating Control */ __IO uint32_t RCGCUART; /*!< Universal Asynchronous Receiver/Transmitter Run Mode Clock Gating Control */ __IO uint32_t RCGCSSI; /*!< Synchronous Serial Interface Run Mode Clock Gating Control */ __IO uint32_t RCGCI2C; /*!< Inter-Integrated Circuit Run Mode Clock Gating Control */ __I uint32_t RESERVED27; __IO uint32_t RCGCUSB; /*!< Universal Serial Bus Run Mode Clock Gating Control */ __I uint32_t RESERVED28[2]; __IO uint32_t RCGCCAN; /*!< Controller Area Network Run Mode Clock Gating Control */ __IO uint32_t RCGCADC; /*!< Analog-to-Digital Converter Run Mode Clock Gating Control */ __IO uint32_t RCGCACMP; /*!< Analog Comparator Run Mode Clock Gating Control */ __IO uint32_t RCGCPWM; /*!< Pulse Width Modulator Run Mode Clock Gating Control */ __IO uint32_t RCGCQEI; /*!< Quadrature Encoder Interface Run Mode Clock Gating Control */ __I uint32_t RESERVED29[4]; __IO uint32_t RCGCEEPROM; /*!< EEPROM Run Mode Clock Gating Control */ __IO uint32_t RCGCWTIMER; /*!< 32/64-Bit Wide General-Purpose Timer Run Mode Clock Gating Control */ __I uint32_t RESERVED30[40]; __IO uint32_t SCGCWD; /*!< Watchdog Timer Sleep Mode Clock Gating Control */ __IO uint32_t SCGCTIMER; /*!< 16/32-Bit General-Purpose Timer Sleep Mode Clock Gating Control */ __IO uint32_t SCGCGPIO; /*!< General-Purpose Input/Output Sleep Mode Clock Gating Control */ __IO uint32_t SCGCDMA; /*!< Micro Direct Memory Access Sleep Mode Clock Gating Control */ __I uint32_t RESERVED31; __IO uint32_t SCGCHIB; /*!< Hibernation Sleep Mode Clock Gating Control */ __IO uint32_t SCGCUART; /*!< Universal Asynchronous Receiver/Transmitter Sleep Mode Clock Gating Control */ __IO uint32_t SCGCSSI; /*!< Synchronous Serial Interface Sleep Mode Clock Gating Control */ __IO uint32_t SCGCI2C; /*!< Inter-Integrated Circuit Sleep Mode Clock Gating Control */ __I uint32_t RESERVED32; __IO uint32_t SCGCUSB; /*!< Universal Serial Bus Sleep Mode Clock Gating Control */ __I uint32_t RESERVED33[2]; __IO uint32_t SCGCCAN; /*!< Controller Area Network Sleep Mode Clock Gating Control */ __IO uint32_t SCGCADC; /*!< Analog-to-Digital Converter Sleep Mode Clock Gating Control */ __IO uint32_t SCGCACMP; /*!< Analog Comparator Sleep Mode Clock Gating Control */ __IO uint32_t SCGCPWM; /*!< Pulse Width Modulator Sleep Mode Clock Gating Control */ __IO uint32_t SCGCQEI; /*!< Quadrature Encoder Interface Sleep Mode Clock Gating Control */ __I uint32_t RESERVED34[4]; __IO uint32_t SCGCEEPROM; /*!< EEPROM Sleep Mode Clock Gating Control */ __IO uint32_t SCGCWTIMER; /*!< 32/64-Bit Wide General-Purpose Timer Sleep Mode Clock Gating Control */ __I uint32_t RESERVED35[40]; __IO uint32_t DCGCWD; /*!< Watchdog Timer Deep-Sleep Mode Clock Gating Control */ __IO uint32_t DCGCTIMER; /*!< 16/32-Bit General-Purpose Timer Deep-Sleep Mode Clock Gating Control */ __IO uint32_t DCGCGPIO; /*!< General-Purpose Input/Output Deep-Sleep Mode Clock Gating Control */ __IO uint32_t DCGCDMA; /*!< Micro Direct Memory Access Deep-Sleep Mode Clock Gating Control */ __I uint32_t RESERVED36; __IO uint32_t DCGCHIB; /*!< Hibernation Deep-Sleep Mode Clock Gating Control */ __IO uint32_t DCGCUART; /*!< Universal Asynchronous Receiver/Transmitter Deep-Sleep Mode Clock Gating Control */ __IO uint32_t DCGCSSI; /*!< Synchronous Serial Interface Deep-Sleep Mode Clock Gating Control */ __IO uint32_t DCGCI2C; /*!< Inter-Integrated Circuit Deep-Sleep Mode Clock Gating Control */ __I uint32_t RESERVED37; __IO uint32_t DCGCUSB; /*!< Universal Serial Bus Deep-Sleep Mode Clock Gating Control */ __I uint32_t RESERVED38[2]; __IO uint32_t DCGCCAN; /*!< Controller Area Network Deep-Sleep Mode Clock Gating Control */ __IO uint32_t DCGCADC; /*!< Analog-to-Digital Converter Deep-Sleep Mode Clock Gating Control */ __IO uint32_t DCGCACMP; /*!< Analog Comparator Deep-Sleep Mode Clock Gating Control */ __IO uint32_t DCGCPWM; /*!< Pulse Width Modulator Deep-Sleep Mode Clock Gating Control */ __IO uint32_t DCGCQEI; /*!< Quadrature Encoder Interface Deep-Sleep Mode Clock Gating Control */ __I uint32_t RESERVED39[4]; __IO uint32_t DCGCEEPROM; /*!< EEPROM Deep-Sleep Mode Clock Gating Control */ __IO uint32_t DCGCWTIMER; /*!< 32/64-Bit Wide General-Purpose Timer Deep-Sleep Mode Clock Gating Control */ __I uint32_t RESERVED40[104]; __IO uint32_t PRWD; /*!< Watchdog Timer Peripheral Ready */ __IO uint32_t PRTIMER; /*!< 16/32-Bit General-Purpose Timer Peripheral Ready */ __IO uint32_t PRGPIO; /*!< General-Purpose Input/Output Peripheral Ready */ __IO uint32_t PRDMA; /*!< Micro Direct Memory Access Peripheral Ready */ __I uint32_t RESERVED41; __IO uint32_t PRHIB; /*!< Hibernation Peripheral Ready */ __IO uint32_t PRUART; /*!< Universal Asynchronous Receiver/Transmitter Peripheral Ready */ __IO uint32_t PRSSI; /*!< Synchronous Serial Interface Peripheral Ready */ __IO uint32_t PRI2C; /*!< Inter-Integrated Circuit Peripheral Ready */ __I uint32_t RESERVED42; __IO uint32_t PRUSB; /*!< Universal Serial Bus Peripheral Ready */ __I uint32_t RESERVED43[2]; __IO uint32_t PRCAN; /*!< Controller Area Network Peripheral Ready */ __IO uint32_t PRADC; /*!< Analog-to-Digital Converter Peripheral Ready */ __IO uint32_t PRACMP; /*!< Analog Comparator Peripheral Ready */ __IO uint32_t PRPWM; /*!< Pulse Width Modulator Peripheral Ready */ __IO uint32_t PRQEI; /*!< Quadrature Encoder Interface Peripheral Ready */ __I uint32_t RESERVED44[4]; __IO uint32_t PREEPROM; /*!< EEPROM Peripheral Ready */ __IO uint32_t PRWTIMER; /*!< 32/64-Bit Wide General-Purpose Timer Peripheral Ready */ } SYSCTL_Type; /* ================================================================================ */ /* ================ UDMA ================ */ /* ================================================================================ */ /** * @brief Register map for UDMA peripheral (UDMA) */ typedef struct { /*!< UDMA Structure */ __IO uint32_t STAT; /*!< DMA Status */ __O uint32_t CFG; /*!< DMA Configuration */ __IO uint32_t CTLBASE; /*!< DMA Channel Control Base Pointer */ __IO uint32_t ALTBASE; /*!< DMA Alternate Channel Control Base Pointer */ __IO uint32_t WAITSTAT; /*!< DMA Channel Wait-on-Request Status */ __O uint32_t SWREQ; /*!< DMA Channel Software Request */ __IO uint32_t USEBURSTSET; /*!< DMA Channel Useburst Set */ __O uint32_t USEBURSTCLR; /*!< DMA Channel Useburst Clear */ __IO uint32_t REQMASKSET; /*!< DMA Channel Request Mask Set */ __O uint32_t REQMASKCLR; /*!< DMA Channel Request Mask Clear */ __IO uint32_t ENASET; /*!< DMA Channel Enable Set */ __O uint32_t ENACLR; /*!< DMA Channel Enable Clear */ __IO uint32_t ALTSET; /*!< DMA Channel Primary Alternate Set */ __O uint32_t ALTCLR; /*!< DMA Channel Primary Alternate Clear */ __IO uint32_t PRIOSET; /*!< DMA Channel Priority Set */ __O uint32_t PRIOCLR; /*!< DMA Channel Priority Clear */ __I uint32_t RESERVED0[3]; __IO uint32_t ERRCLR; /*!< DMA Bus Error Clear */ __I uint32_t RESERVED1[300]; __IO uint32_t CHASGN; /*!< DMA Channel Assignment */ __IO uint32_t CHIS; /*!< DMA Channel Interrupt Status */ __I uint32_t RESERVED2[2]; __IO uint32_t CHMAP0; /*!< DMA Channel Map Select 0 */ __IO uint32_t CHMAP1; /*!< DMA Channel Map Select 1 */ __IO uint32_t CHMAP2; /*!< DMA Channel Map Select 2 */ __IO uint32_t CHMAP3; /*!< DMA Channel Map Select 3 */ } UDMA_Type; /* -------------------- End of section using anonymous unions ------------------- */ #if defined(__CC_ARM) #pragma pop #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* anonymous unions are enabled by default */ #elif defined(__ICCARM__) /* leave anonymous unions enabled */ #elif defined(__GNUC__) /* anonymous unions are enabled by default */ #elif defined(__TMS470__) /* anonymous unions are enabled by default */ #elif defined(__TASKING__) #pragma warning restore #else #warning Not supported compiler type #endif /* ================================================================================ */ /* ================ Peripheral memory map ================ */ /* ================================================================================ */ #define WATCHDOG0_BASE 0x40000000UL #define WATCHDOG1_BASE 0x40001000UL #define GPIOA_BASE 0x40004000UL #define GPIOB_BASE 0x40005000UL #define GPIOC_BASE 0x40006000UL #define GPIOD_BASE 0x40007000UL #define SSI0_BASE 0x40008000UL #define SSI1_BASE 0x40009000UL #define SSI2_BASE 0x4000A000UL #define SSI3_BASE 0x4000B000UL #define UART0_BASE 0x4000C000UL #define UART1_BASE 0x4000D000UL #define UART2_BASE 0x4000E000UL #define UART3_BASE 0x4000F000UL #define UART4_BASE 0x40010000UL #define UART5_BASE 0x40011000UL #define UART6_BASE 0x40012000UL #define UART7_BASE 0x40013000UL #define I2C0_BASE 0x40020000UL #define I2C1_BASE 0x40021000UL #define I2C2_BASE 0x40022000UL #define I2C3_BASE 0x40023000UL #define GPIOE_BASE 0x40024000UL #define GPIOF_BASE 0x40025000UL #define PWM0_BASE 0x40028000UL #define PWM1_BASE 0x40029000UL #define QEI0_BASE 0x4002C000UL #define QEI1_BASE 0x4002D000UL #define TIMER0_BASE 0x40030000UL #define TIMER1_BASE 0x40031000UL #define TIMER2_BASE 0x40032000UL #define TIMER3_BASE 0x40033000UL #define TIMER4_BASE 0x40034000UL #define TIMER5_BASE 0x40035000UL #define WTIMER0_BASE 0x40036000UL #define WTIMER1_BASE 0x40037000UL #define ADC0_BASE 0x40038000UL #define ADC1_BASE 0x40039000UL #define COMP_BASE 0x4003C000UL #define CAN0_BASE 0x40040000UL #define CAN1_BASE 0x40041000UL #define WTIMER2_BASE 0x4004C000UL #define WTIMER3_BASE 0x4004D000UL #define WTIMER4_BASE 0x4004E000UL #define WTIMER5_BASE 0x4004F000UL #define USB0_BASE 0x40050000UL #define GPIOA_AHB_BASE 0x40058000UL #define GPIOB_AHB_BASE 0x40059000UL #define GPIOC_AHB_BASE 0x4005A000UL #define GPIOD_AHB_BASE 0x4005B000UL #define GPIOE_AHB_BASE 0x4005C000UL #define GPIOF_AHB_BASE 0x4005D000UL #define EEPROM_BASE 0x400AF000UL #define SYSEXC_BASE 0x400F9000UL #define HIB_BASE 0x400FC000UL #define FLASH_CTRL_BASE 0x400FD000UL #define SYSCTL_BASE 0x400FE000UL #define UDMA_BASE 0x400FF000UL /* ================================================================================ */ /* ================ Peripheral declaration ================ */ /* ================================================================================ */ #define WATCHDOG0 ((WATCHDOG0_Type *) WATCHDOG0_BASE) #define WATCHDOG1 ((WATCHDOG0_Type *) WATCHDOG1_BASE) #define GPIOA ((GPIOA_Type *) GPIOA_BASE) #define GPIOB ((GPIOA_Type *) GPIOB_BASE) #define GPIOC ((GPIOA_Type *) GPIOC_BASE) #define GPIOD ((GPIOA_Type *) GPIOD_BASE) #define SSI0 ((SSI0_Type *) SSI0_BASE) #define SSI1 ((SSI0_Type *) SSI1_BASE) #define SSI2 ((SSI0_Type *) SSI2_BASE) #define SSI3 ((SSI0_Type *) SSI3_BASE) #define UART0 ((UART0_Type *) UART0_BASE) #define UART1 ((UART0_Type *) UART1_BASE) #define UART2 ((UART0_Type *) UART2_BASE) #define UART3 ((UART0_Type *) UART3_BASE) #define UART4 ((UART0_Type *) UART4_BASE) #define UART5 ((UART0_Type *) UART5_BASE) #define UART6 ((UART0_Type *) UART6_BASE) #define UART7 ((UART0_Type *) UART7_BASE) #define I2C0 ((I2C0_Type *) I2C0_BASE) #define I2C1 ((I2C0_Type *) I2C1_BASE) #define I2C2 ((I2C0_Type *) I2C2_BASE) #define I2C3 ((I2C0_Type *) I2C3_BASE) #define GPIOE ((GPIOA_Type *) GPIOE_BASE) #define GPIOF ((GPIOA_Type *) GPIOF_BASE) #define PWM0 ((PWM0_Type *) PWM0_BASE) #define PWM1 ((PWM0_Type *) PWM1_BASE) #define QEI0 ((QEI0_Type *) QEI0_BASE) #define QEI1 ((QEI0_Type *) QEI1_BASE) #define TIMER0 ((TIMER0_Type *) TIMER0_BASE) #define TIMER1 ((TIMER0_Type *) TIMER1_BASE) #define TIMER2 ((TIMER0_Type *) TIMER2_BASE) #define TIMER3 ((TIMER0_Type *) TIMER3_BASE) #define TIMER4 ((TIMER0_Type *) TIMER4_BASE) #define TIMER5 ((TIMER0_Type *) TIMER5_BASE) #define WTIMER0 ((WTIMER0_Type *) WTIMER0_BASE) #define WTIMER1 ((TIMER0_Type *) WTIMER1_BASE) #define ADC0 ((ADC0_Type *) ADC0_BASE) #define ADC1 ((ADC0_Type *) ADC1_BASE) #define COMP ((COMP_Type *) COMP_BASE) #define CAN0 ((CAN0_Type *) CAN0_BASE) #define CAN1 ((CAN0_Type *) CAN1_BASE) #define WTIMER2 ((TIMER0_Type *) WTIMER2_BASE) #define WTIMER3 ((TIMER0_Type *) WTIMER3_BASE) #define WTIMER4 ((TIMER0_Type *) WTIMER4_BASE) #define WTIMER5 ((TIMER0_Type *) WTIMER5_BASE) #define USB0 ((USB0_Type *) USB0_BASE) #define GPIOA_AHB ((GPIOA_Type *) GPIOA_AHB_BASE) #define GPIOB_AHB ((GPIOA_Type *) GPIOB_AHB_BASE) #define GPIOC_AHB ((GPIOA_Type *) GPIOC_AHB_BASE) #define GPIOD_AHB ((GPIOA_Type *) GPIOD_AHB_BASE) #define GPIOE_AHB ((GPIOA_Type *) GPIOE_AHB_BASE) #define GPIOF_AHB ((GPIOA_Type *) GPIOF_AHB_BASE) #define EEPROM ((EEPROM_Type *) EEPROM_BASE) #define SYSEXC ((SYSEXC_Type *) SYSEXC_BASE) #define HIB ((HIB_Type *) HIB_BASE) #define FLASH_CTRL ((FLASH_CTRL_Type *) FLASH_CTRL_BASE) #define SYSCTL ((SYSCTL_Type *) SYSCTL_BASE) #define UDMA ((UDMA_Type *) UDMA_BASE) /** @} */ /* End of group Device_Peripheral_Registers */ /** @} */ /* End of group TM4C123GH6PM */ /** @} */ /* End of group Texas Instruments */ #ifdef __cplusplus } #endif #endif /* TM4C123GH6PM_H */ ================================================ FILE: 3rd_party/ek-tm4c123gxl/arm/startup_TM4C123GH6PM.s ================================================ ;/***************************************************************************/ ; * @file startup_TM4C123GH6PM.s for ARM-KEIL ARM assembler ; * @brief CMSIS Cortex-M4F Core Device Startup File for TM4C123GH6PM ; * @version CMSIS 5.9.0 ; * @date 1 Feb 2023 ; * ; * Modified by Quantum Leaps: ; * - Added relocating of the Vector Table to free up the 256B region at 0x0 ; * for NULL-pointer protection by the MPU. ; * - Modified all exception handlers to branch to assert_failed() ; * instead of locking up the CPU inside an endless loop. ; * ; * @description ; * Created from the CMSIS template for the specified device ; * Quantum Leaps, www.state-machine.com ; * ; * @note ; * The symbols Stack_Size and Heap_Size should be provided on the command- ; * line options to the assembler, for example as: ; * --pd "Stack_Size SETA 1024" --pd "Heap_Size SETA 0" ;****************************************************************************** ; Allocate space for the stack. ; AREA STACK, NOINIT, READWRITE, ALIGN=3 __stack_base StackMem SPACE Stack_Size ; provided in command-line option, for example: ; --pd "Stack_Size SETA 512" __stack_limit __initial_sp ;****************************************************************************** ; Allocate space for the heap. ; AREA HEAP, NOINIT, READWRITE, ALIGN=3 __heap_base HeapMem SPACE Heap_Size ; provided in command-line option, for example: ; --pd "Heap_Size SETA 0" __heap_limit ; Indicate that the code in this file preserves 8-byte alignment of the stack. PRESERVE8 ;****************************************************************************** ; The vector table. ; ; Place code into the reset code section. AREA RESET, DATA, READONLY, ALIGN=8 EXPORT __Vectors EXPORT __Vectors_End EXPORT __Vectors_Size __Vectors ; Initial Vector Table before relocation DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU fault handler DCD BusFault_Handler ; Bus fault handler DCD UsageFault_Handler ; Usage fault handler DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD SVC_Handler ; SVCall handler DCD DebugMon_Handler ; Debug Monitor handler DCD Default_Handler ; Reserved DCD PendSV_Handler ; PendSV handler DCD SysTick_Handler ; SysTick handler ALIGN 256 ; Extend the initial Vector Table to the 256B boundary ; Relocated Vector Table beyond the 256B region around address 0. ; That region is used for NULL-pointer protection by the MPU. __relocated_vector_table DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU fault handler DCD BusFault_Handler ; Bus fault handler DCD UsageFault_Handler ; Usage fault handler DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD SVC_Handler ; SVCall handler DCD DebugMon_Handler ; Debug Monitor handler DCD Default_Handler ; Reserved DCD PendSV_Handler ; PendSV handler DCD SysTick_Handler ; SysTick handler ; IRQ handlers... DCD GPIOPortA_IRQHandler ; GPIO Port A DCD GPIOPortB_IRQHandler ; GPIO Port B DCD GPIOPortC_IRQHandler ; GPIO Port C DCD GPIOPortD_IRQHandler ; GPIO Port D DCD GPIOPortE_IRQHandler ; GPIO Port E DCD UART0_IRQHandler ; UART0 Rx and Tx DCD UART1_IRQHandler ; UART1 Rx and Tx DCD SSI0_IRQHandler ; SSI0 Rx and Tx DCD I2C0_IRQHandler ; I2C0 Master and Slave DCD PWMFault_IRQHandler ; PWM Fault DCD PWMGen0_IRQHandler ; PWM Generator 0 DCD PWMGen1_IRQHandler ; PWM Generator 1 DCD PWMGen2_IRQHandler ; PWM Generator 2 DCD QEI0_IRQHandler ; Quadrature Encoder 0 DCD ADCSeq0_IRQHandler ; ADC Sequence 0 DCD ADCSeq1_IRQHandler ; ADC Sequence 1 DCD ADCSeq2_IRQHandler ; ADC Sequence 2 DCD ADCSeq3_IRQHandler ; ADC Sequence 3 DCD Watchdog_IRQHandler ; Watchdog timer DCD Timer0A_IRQHandler ; Timer 0 subtimer A DCD Timer0B_IRQHandler ; Timer 0 subtimer B DCD Timer1A_IRQHandler ; Timer 1 subtimer A DCD Timer1B_IRQHandler ; Timer 1 subtimer B DCD Timer2A_IRQHandler ; Timer 2 subtimer A DCD Timer2B_IRQHandler ; Timer 2 subtimer B DCD Comp0_IRQHandler ; Analog Comparator 0 DCD Comp1_IRQHandler ; Analog Comparator 1 DCD Comp2_IRQHandler ; Analog Comparator 2 DCD SysCtrl_IRQHandler ; System Control (PLL, OSC, BO) DCD FlashCtrl_IRQHandler ; FLASH Control DCD GPIOPortF_IRQHandler ; GPIO Port F DCD GPIOPortG_IRQHandler ; GPIO Port G DCD GPIOPortH_IRQHandler ; GPIO Port H DCD UART2_IRQHandler ; UART2 Rx and Tx DCD SSI1_IRQHandler ; SSI1 Rx and Tx DCD Timer3A_IRQHandler ; Timer 3 subtimer A DCD Timer3B_IRQHandler ; Timer 3 subtimer B DCD I2C1_IRQHandler ; I2C1 Master and Slave DCD QEI1_IRQHandler ; Quadrature Encoder 1 DCD CAN0_IRQHandler ; CAN0 DCD CAN1_IRQHandler ; CAN1 DCD CAN2_IRQHandler ; CAN2 DCD Default_Handler ; Reserved DCD Hibernate_IRQHandler ; Hibernate DCD USB0_IRQHandler ; USB0 DCD PWMGen3_IRQHandler ; PWM Generator 3 DCD uDMAST_IRQHandler ; uDMA Software Transfer DCD uDMAError_IRQHandler ; uDMA Error DCD ADC1Seq0_IRQHandler ; ADC1 Sequence 0 DCD ADC1Seq1_IRQHandler ; ADC1 Sequence 1 DCD ADC1Seq2_IRQHandler ; ADC1 Sequence 2 DCD ADC1Seq3_IRQHandler ; ADC1 Sequence 3 DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD GPIOPortJ_IRQHandler ; GPIO Port J DCD GPIOPortK_IRQHandler ; GPIO Port K DCD GPIOPortL_IRQHandler ; GPIO Port L DCD SSI2_IRQHandler ; SSI2 Rx and Tx DCD SSI3_IRQHandler ; SSI3 Rx and Tx DCD UART3_IRQHandler ; UART3 Rx and Tx DCD UART4_IRQHandler ; UART4 Rx and Tx DCD UART5_IRQHandler ; UART5 Rx and Tx DCD UART6_IRQHandler ; UART6 Rx and Tx DCD UART7_IRQHandler ; UART7 Rx and Tx DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD I2C2_IRQHandler ; I2C2 Master and Slave DCD I2C3_IRQHandler ; I2C3 Master and Slave DCD Timer4A_IRQHandler ; Timer 4 subtimer A DCD Timer4B_IRQHandler ; Timer 4 subtimer B DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Timer5A_IRQHandler ; Timer 5 subtimer A DCD Timer5B_IRQHandler ; Timer 5 subtimer B DCD WideTimer0A_IRQHandler ; Wide Timer 0 subtimer A DCD WideTimer0B_IRQHandler ; Wide Timer 0 subtimer B DCD WideTimer1A_IRQHandler ; Wide Timer 1 subtimer A DCD WideTimer1B_IRQHandler ; Wide Timer 1 subtimer B DCD WideTimer2A_IRQHandler ; Wide Timer 2 subtimer A DCD WideTimer2B_IRQHandler ; Wide Timer 2 subtimer B DCD WideTimer3A_IRQHandler ; Wide Timer 3 subtimer A DCD WideTimer3B_IRQHandler ; Wide Timer 3 subtimer B DCD WideTimer4A_IRQHandler ; Wide Timer 4 subtimer A DCD WideTimer4B_IRQHandler ; Wide Timer 4 subtimer B DCD WideTimer5A_IRQHandler ; Wide Timer 5 subtimer A DCD WideTimer5B_IRQHandler ; Wide Timer 5 subtimer B DCD FPU_IRQHandler ; FPU DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD I2C4_IRQHandler ; I2C4 Master and Slave DCD I2C5_IRQHandler ; I2C5 Master and Slave DCD GPIOPortM_IRQHandler ; GPIO Port M DCD GPIOPortN_IRQHandler ; GPIO Port N DCD QEI2_IRQHandler ; Quadrature Encoder 2 DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD GPIOPortP0_IRQHandler ; GPIO Port P (Summary or P0) DCD GPIOPortP1_IRQHandler ; GPIO Port P1 DCD GPIOPortP2_IRQHandler ; GPIO Port P2 DCD GPIOPortP3_IRQHandler ; GPIO Port P3 DCD GPIOPortP4_IRQHandler ; GPIO Port P4 DCD GPIOPortP5_IRQHandler ; GPIO Port P5 DCD GPIOPortP6_IRQHandler ; GPIO Port P6 DCD GPIOPortP7_IRQHandler ; GPIO Port P7 DCD GPIOPortQ0_IRQHandler ; GPIO Port Q (Summary or Q0) DCD GPIOPortQ1_IRQHandler ; GPIO Port Q1 DCD GPIOPortQ2_IRQHandler ; GPIO Port Q2 DCD GPIOPortQ3_IRQHandler ; GPIO Port Q3 DCD GPIOPortQ4_IRQHandler ; GPIO Port Q4 DCD GPIOPortQ5_IRQHandler ; GPIO Port Q5 DCD GPIOPortQ6_IRQHandler ; GPIO Port Q6 DCD GPIOPortQ7_IRQHandler ; GPIO Port Q7 DCD GPIOPortR_IRQHandler ; GPIO Port R DCD GPIOPortS_IRQHandler ; GPIO Port S DCD PWM1Gen0_IRQHandler ; PWM 1 Generator 0 DCD PWM1Gen1_IRQHandler ; PWM 1 Generator 1 DCD PWM1Gen2_IRQHandler ; PWM 1 Generator 2 DCD PWM1Gen3_IRQHandler ; PWM 1 Generator 3 DCD PWM1Fault_IRQHandler ; PWM 1 Fault __Vectors_End __Vectors_Size EQU __Vectors_End - __Vectors ;****************************************************************************** ; This is the code for exception handlers. ; AREA |.text|, CODE, READONLY ;****************************************************************************** ; This is the code that gets called when the processor first starts execution ; following a reset event. ; Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main IMPORT assert_failed ; relocate the Vector Table LDR r0,=0xE000ED08 ; System Control Block/Vector Table Offset Reg LDR r1,=__relocated_vector_table STR r1,[r0] ; SCB->VTOR := __relocated_vector_table LDR r0,=SystemInit ; CMSIS system initialization BLX r0 ; Call the C library enty point that handles startup. This will copy ; the .data section initializers from flash to SRAM and zero fill the ; .bss section. ; NOTE: The __main function clears the C stack as well LDR r0,=__main BX r0 ; __main calls the main() function, which should not return, ; but just in case jump to assert_failed() if main returns. LDR r0,=str_EXIT MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_EXIT DCB "EXIT" ALIGN ENDP ;****************************************************************************** NMI_Handler PROC EXPORT NMI_Handler [WEAK] IMPORT assert_failed LDR r0,=str_NMI MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_NMI DCB "NMI" ALIGN ENDP ;****************************************************************************** HardFault_Handler PROC EXPORT HardFault_Handler [WEAK] IMPORT assert_failed LDR r0,=str_HardFault MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_HardFault DCB "HardFault" ALIGN ENDP ;****************************************************************************** MemManage_Handler PROC EXPORT MemManage_Handler [WEAK] IMPORT assert_failed LDR r0,=str_MemManage MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_MemManage DCB "MemManage" ALIGN ENDP ;****************************************************************************** BusFault_Handler PROC EXPORT BusFault_Handler [WEAK] IMPORT assert_failed LDR r0,=str_BusFault MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_BusFault DCB "BusFault" ALIGN ENDP ;****************************************************************************** UsageFault_Handler PROC EXPORT UsageFault_Handler [WEAK] IMPORT assert_failed LDR r0,=str_UsageFault MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_UsageFault DCB "UsageFault" ALIGN ENDP ;****************************************************************************** ; ; Weak non-fault handlers... ; ;****************************************************************************** SVC_Handler PROC EXPORT SVC_Handler [WEAK] IMPORT assert_failed LDR r0,=str_SVC MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_SVC DCB "SVC" ALIGN ENDP ;****************************************************************************** DebugMon_Handler PROC EXPORT DebugMon_Handler [WEAK] IMPORT assert_failed LDR r0,=str_DebugMon MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_DebugMon DCB "DebugMon" ALIGN ENDP ;****************************************************************************** PendSV_Handler PROC EXPORT PendSV_Handler [WEAK] IMPORT assert_failed LDR r0,=str_PendSV MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_PendSV DCB "PendSV" ALIGN ENDP ;****************************************************************************** SysTick_Handler PROC EXPORT SysTick_Handler [WEAK] IMPORT assert_failed LDR r0,=str_SysTick MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_SysTick DCB "SysTick" ALIGN ENDP ;****************************************************************************** Default_Handler PROC EXPORT GPIOPortA_IRQHandler [WEAK] EXPORT GPIOPortB_IRQHandler [WEAK] EXPORT GPIOPortC_IRQHandler [WEAK] EXPORT GPIOPortD_IRQHandler [WEAK] EXPORT GPIOPortE_IRQHandler [WEAK] EXPORT UART0_IRQHandler [WEAK] EXPORT UART1_IRQHandler [WEAK] EXPORT SSI0_IRQHandler [WEAK] EXPORT I2C0_IRQHandler [WEAK] EXPORT PWMFault_IRQHandler [WEAK] EXPORT PWMGen0_IRQHandler [WEAK] EXPORT PWMGen1_IRQHandler [WEAK] EXPORT PWMGen2_IRQHandler [WEAK] EXPORT QEI0_IRQHandler [WEAK] EXPORT ADCSeq0_IRQHandler [WEAK] EXPORT ADCSeq1_IRQHandler [WEAK] EXPORT ADCSeq2_IRQHandler [WEAK] EXPORT ADCSeq3_IRQHandler [WEAK] EXPORT Watchdog_IRQHandler [WEAK] EXPORT Timer0A_IRQHandler [WEAK] EXPORT Timer0B_IRQHandler [WEAK] EXPORT Timer1A_IRQHandler [WEAK] EXPORT Timer1B_IRQHandler [WEAK] EXPORT Timer2A_IRQHandler [WEAK] EXPORT Timer2B_IRQHandler [WEAK] EXPORT Comp0_IRQHandler [WEAK] EXPORT Comp1_IRQHandler [WEAK] EXPORT Comp2_IRQHandler [WEAK] EXPORT SysCtrl_IRQHandler [WEAK] EXPORT FlashCtrl_IRQHandler [WEAK] EXPORT GPIOPortF_IRQHandler [WEAK] EXPORT GPIOPortG_IRQHandler [WEAK] EXPORT GPIOPortH_IRQHandler [WEAK] EXPORT UART2_IRQHandler [WEAK] EXPORT SSI1_IRQHandler [WEAK] EXPORT Timer3A_IRQHandler [WEAK] EXPORT Timer3B_IRQHandler [WEAK] EXPORT I2C1_IRQHandler [WEAK] EXPORT QEI1_IRQHandler [WEAK] EXPORT CAN0_IRQHandler [WEAK] EXPORT CAN1_IRQHandler [WEAK] EXPORT CAN2_IRQHandler [WEAK] EXPORT Hibernate_IRQHandler [WEAK] EXPORT USB0_IRQHandler [WEAK] EXPORT PWMGen3_IRQHandler [WEAK] EXPORT uDMAST_IRQHandler [WEAK] EXPORT uDMAError_IRQHandler [WEAK] EXPORT ADC1Seq0_IRQHandler [WEAK] EXPORT ADC1Seq1_IRQHandler [WEAK] EXPORT ADC1Seq2_IRQHandler [WEAK] EXPORT ADC1Seq3_IRQHandler [WEAK] EXPORT GPIOPortJ_IRQHandler [WEAK] EXPORT GPIOPortK_IRQHandler [WEAK] EXPORT GPIOPortL_IRQHandler [WEAK] EXPORT SSI2_IRQHandler [WEAK] EXPORT SSI3_IRQHandler [WEAK] EXPORT UART3_IRQHandler [WEAK] EXPORT UART4_IRQHandler [WEAK] EXPORT UART5_IRQHandler [WEAK] EXPORT UART6_IRQHandler [WEAK] EXPORT UART7_IRQHandler [WEAK] EXPORT I2C2_IRQHandler [WEAK] EXPORT I2C3_IRQHandler [WEAK] EXPORT Timer4A_IRQHandler [WEAK] EXPORT Timer4B_IRQHandler [WEAK] EXPORT Timer5A_IRQHandler [WEAK] EXPORT Timer5B_IRQHandler [WEAK] EXPORT WideTimer0A_IRQHandler [WEAK] EXPORT WideTimer0B_IRQHandler [WEAK] EXPORT WideTimer1A_IRQHandler [WEAK] EXPORT WideTimer1B_IRQHandler [WEAK] EXPORT WideTimer2A_IRQHandler [WEAK] EXPORT WideTimer2B_IRQHandler [WEAK] EXPORT WideTimer3A_IRQHandler [WEAK] EXPORT WideTimer3B_IRQHandler [WEAK] EXPORT WideTimer4A_IRQHandler [WEAK] EXPORT WideTimer4B_IRQHandler [WEAK] EXPORT WideTimer5A_IRQHandler [WEAK] EXPORT WideTimer5B_IRQHandler [WEAK] EXPORT FPU_IRQHandler [WEAK] EXPORT I2C4_IRQHandler [WEAK] EXPORT I2C5_IRQHandler [WEAK] EXPORT GPIOPortM_IRQHandler [WEAK] EXPORT GPIOPortN_IRQHandler [WEAK] EXPORT QEI2_IRQHandler [WEAK] EXPORT GPIOPortP0_IRQHandler [WEAK] EXPORT GPIOPortP1_IRQHandler [WEAK] EXPORT GPIOPortP2_IRQHandler [WEAK] EXPORT GPIOPortP3_IRQHandler [WEAK] EXPORT GPIOPortP4_IRQHandler [WEAK] EXPORT GPIOPortP5_IRQHandler [WEAK] EXPORT GPIOPortP6_IRQHandler [WEAK] EXPORT GPIOPortP7_IRQHandler [WEAK] EXPORT GPIOPortQ0_IRQHandler [WEAK] EXPORT GPIOPortQ1_IRQHandler [WEAK] EXPORT GPIOPortQ2_IRQHandler [WEAK] EXPORT GPIOPortQ3_IRQHandler [WEAK] EXPORT GPIOPortQ4_IRQHandler [WEAK] EXPORT GPIOPortQ5_IRQHandler [WEAK] EXPORT GPIOPortQ6_IRQHandler [WEAK] EXPORT GPIOPortQ7_IRQHandler [WEAK] EXPORT GPIOPortR_IRQHandler [WEAK] EXPORT GPIOPortS_IRQHandler [WEAK] EXPORT PWM1Gen0_IRQHandler [WEAK] EXPORT PWM1Gen1_IRQHandler [WEAK] EXPORT PWM1Gen2_IRQHandler [WEAK] EXPORT PWM1Gen3_IRQHandler [WEAK] EXPORT PWM1Fault_IRQHandler [WEAK] GPIOPortA_IRQHandler GPIOPortB_IRQHandler GPIOPortC_IRQHandler GPIOPortD_IRQHandler GPIOPortE_IRQHandler UART0_IRQHandler UART1_IRQHandler SSI0_IRQHandler I2C0_IRQHandler PWMFault_IRQHandler PWMGen0_IRQHandler PWMGen1_IRQHandler PWMGen2_IRQHandler QEI0_IRQHandler ADCSeq0_IRQHandler ADCSeq1_IRQHandler ADCSeq2_IRQHandler ADCSeq3_IRQHandler Watchdog_IRQHandler Timer0A_IRQHandler Timer0B_IRQHandler Timer1A_IRQHandler Timer1B_IRQHandler Timer2A_IRQHandler Timer2B_IRQHandler Comp0_IRQHandler Comp1_IRQHandler Comp2_IRQHandler SysCtrl_IRQHandler FlashCtrl_IRQHandler GPIOPortF_IRQHandler GPIOPortG_IRQHandler GPIOPortH_IRQHandler UART2_IRQHandler SSI1_IRQHandler Timer3A_IRQHandler Timer3B_IRQHandler I2C1_IRQHandler QEI1_IRQHandler CAN0_IRQHandler CAN1_IRQHandler CAN2_IRQHandler Hibernate_IRQHandler USB0_IRQHandler PWMGen3_IRQHandler uDMAST_IRQHandler uDMAError_IRQHandler ADC1Seq0_IRQHandler ADC1Seq1_IRQHandler ADC1Seq2_IRQHandler ADC1Seq3_IRQHandler GPIOPortJ_IRQHandler GPIOPortK_IRQHandler GPIOPortL_IRQHandler SSI2_IRQHandler SSI3_IRQHandler UART3_IRQHandler UART4_IRQHandler UART5_IRQHandler UART6_IRQHandler UART7_IRQHandler I2C2_IRQHandler I2C3_IRQHandler Timer4A_IRQHandler Timer4B_IRQHandler Timer5A_IRQHandler Timer5B_IRQHandler WideTimer0A_IRQHandler WideTimer0B_IRQHandler WideTimer1A_IRQHandler WideTimer1B_IRQHandler WideTimer2A_IRQHandler WideTimer2B_IRQHandler WideTimer3A_IRQHandler WideTimer3B_IRQHandler WideTimer4A_IRQHandler WideTimer4B_IRQHandler WideTimer5A_IRQHandler WideTimer5B_IRQHandler FPU_IRQHandler I2C4_IRQHandler I2C5_IRQHandler GPIOPortM_IRQHandler GPIOPortN_IRQHandler QEI2_IRQHandler GPIOPortP0_IRQHandler GPIOPortP1_IRQHandler GPIOPortP2_IRQHandler GPIOPortP3_IRQHandler GPIOPortP4_IRQHandler GPIOPortP5_IRQHandler GPIOPortP6_IRQHandler GPIOPortP7_IRQHandler GPIOPortQ0_IRQHandler GPIOPortQ1_IRQHandler GPIOPortQ2_IRQHandler GPIOPortQ3_IRQHandler GPIOPortQ4_IRQHandler GPIOPortQ5_IRQHandler GPIOPortQ6_IRQHandler GPIOPortQ7_IRQHandler GPIOPortR_IRQHandler GPIOPortS_IRQHandler PWM1Gen0_IRQHandler PWM1Gen1_IRQHandler PWM1Gen2_IRQHandler PWM1Gen3_IRQHandler PWM1Fault_IRQHandler IMPORT assert_failed LDR r0,=str_Undefined MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_Undefined DCB "Undefined" ALIGN ENDP ALIGN ; make sure the end of this section is aligned ;****************************************************************************** ; The function expected of the C library startup code for defining the stack ; and heap memory locations. For the C library version of the startup code, ; provide this function so that the C library initialization code can find out ; the location of the stack and heap. ; IF :DEF: __MICROLIB EXPORT __initial_sp EXPORT __stack_limit EXPORT __heap_base EXPORT __heap_limit ELSE IMPORT __use_two_region_memory EXPORT __user_initial_stackheap __user_initial_stackheap PROC LDR R0, =__heap_base LDR R1, =__stack_limit LDR R2, =__heap_limit LDR R3, =__stack_base BX LR ENDP ENDIF ALIGN ; make sure the end of this section is aligned END ; end of module ================================================ FILE: 3rd_party/ek-tm4c123gxl/gnu/ek-tm4c123gxl.ld ================================================ /***************************************************************************** * Product: Linker script for EK-TM4C123GXL, GNU-ARM linker * Last Updated for Version: 5.9.8 * Date of the Last Update: 2017-09-13 * * Q u a n t u m L e a P s * --------------------------- * innovating embedded systems * * Copyright (C) Quantum Leaps, LLC. All rights reserved. * *****************************************************************************/ OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(Reset_Handler) /* entry Point */ MEMORY { /* memory map of Tiva TM4C123GH6PM */ ROM (rx) : ORIGIN = 0x00000000, LENGTH = 256K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K } /* The size of the stack used by the application. NOTE: you need to adjust */ STACK_SIZE = 2048; /* The size of the heap used by the application. NOTE: you need to adjust */ HEAP_SIZE = 0; SECTIONS { .isr_vector : { /* the vector table goes FIRST into ROM */ KEEP(*(.isr_vector)) /* vector table */ . = ALIGN(4); } >ROM .text : { /* code and constants */ . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); } >ROM .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >ROM .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >ROM .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(.fini_array*)) KEEP (*(SORT(.fini_array.*))) PROVIDE_HIDDEN (__fini_array_end = .); } >ROM _etext = .; /* global symbols at end of code */ .stack : { __stack_start__ = .; . = . + STACK_SIZE; . = ALIGN(4); __stack_end__ = .; } >RAM .data : AT (_etext) { __data_load = LOADADDR (.data); __data_start = .; *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); __data_end__ = .; _edata = __data_end__; } >RAM .bss : { __bss_start__ = .; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = .; } >RAM __exidx_start = .; .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM __exidx_end = .; PROVIDE ( end = _ebss ); PROVIDE ( _end = _ebss ); PROVIDE ( __end__ = _ebss ); .heap : { __heap_start__ = .; . = . + HEAP_SIZE; . = ALIGN(4); __heap_end__ = .; } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } } ================================================ FILE: 3rd_party/ek-tm4c123gxl/gnu/startup_TM4C123GH6PM.c ================================================ /* File: startup_TM4C123GH6PM.c for GNU-ARM * Purpose: startup file for TM4C123GH6PM Cortex-M4 device. * Should be used with GCC 'GNU Tools ARM Embedded' * Version: CMSIS 5.0.1 * Date: 2017-09-13 * * Modified by Quantum Leaps: * - Added relocating of the Vector Table to free up the 256B region at 0x0 * for NULL-pointer protection by the MPU. * - Modified all exception handlers to branch to assert_failed() * instead of locking up the CPU inside an endless loop. * * Created from the CMSIS template for the specified device * Quantum Leaps, www.state-machine.com * * NOTE: * The function assert_failed defined at the end of this file defines * the error/assertion handling policy for the application and might * need to be customized for each project. This function is defined in * assembly to re-set the stack pointer, in case it is corrupted by the * time assert_failed is called. */ /* start and end of stack defined in the linker script ---------------------*/ /*extern int __stack_start__;*/ extern int __stack_end__; /* Weak prototypes for error handlers --------------------------------------*/ /** * \note * The function assert_failed defined at the end of this file defines * the error/assertion handling policy for the application and might * need to be customized for each project. This function is defined in * assembly to avoid accessing the stack, which might be corrupted by * the time assert_failed is called. */ __attribute__ ((naked, noreturn)) void assert_failed(char const *module, int loc); /* Function prototypes -----------------------------------------------------*/ void Default_Handler(void); /* Default empty handler */ void Reset_Handler(void); /* Reset Handler */ void SystemInit(void); /* CMSIS system initialization */ /*---------------------------------------------------------------------------- * weak aliases for each Exception handler to the Default_Handler. * Any function with the same name will override these definitions. */ /* Cortex-M Processor fault exceptions... */ void NMI_Handler (void) __attribute__ ((weak)); void HardFault_Handler (void) __attribute__ ((weak)); void MemManage_Handler (void) __attribute__ ((weak)); void BusFault_Handler (void) __attribute__ ((weak)); void UsageFault_Handler (void) __attribute__ ((weak)); /* Cortex-M Processor non-fault exceptions... */ void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); void DebugMon_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); /* external interrupts... */ void GPIOPortA_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortB_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortD_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortE_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void UART0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void UART1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void SSI0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void I2C0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void PWMFault_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void PWMGen0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void PWMGen1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void PWMGen2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void QEI0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void ADCSeq0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void ADCSeq1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void ADCSeq2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void ADCSeq3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Watchdog_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Timer0A_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Timer0B_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Timer1A_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Timer1B_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Timer2A_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Timer2B_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Comp0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Comp1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Comp2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void SysCtrl_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void FlashCtrl_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortF_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortG_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortH_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void UART2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void SSI1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Timer3A_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Timer3B_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void I2C1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void QEI1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void CAN0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void CAN1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void CAN2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Hibernate_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void USB0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void PWMGen3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void uDMAST_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void uDMAError_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void ADC1Seq0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void ADC1Seq1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void ADC1Seq2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void ADC1Seq3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortJ_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortK_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortL_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void SSI2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void SSI3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void UART3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void UART4_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void UART5_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void UART6_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void UART7_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void I2C2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void I2C3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Timer4A_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Timer4B_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Timer5A_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Timer5B_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void WideTimer0A_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void WideTimer0B_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void WideTimer1A_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void WideTimer1B_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void WideTimer2A_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void WideTimer2B_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void WideTimer3A_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void WideTimer3B_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void WideTimer4A_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void WideTimer4B_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void WideTimer5A_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void WideTimer5B_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void FPU_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void I2C4_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void I2C5_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortM_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortN_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void QEI2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortP0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortP1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortP2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortP3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortP4_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortP5_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortP6_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortP7_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortQ0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortQ1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortQ2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortQ3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortQ4_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortQ5_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortQ6_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortQ7_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortR_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void GPIOPortS_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void PWM1Gen0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void PWM1Gen1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void PWM1Gen2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void PWM1Gen3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void PWM1Fault_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); /*..........................................................................*/ __attribute__ ((section(".isr_vector"))) int const g_pfnVectors[] = { /* Initial Vector Table before relocation */ (int)&__stack_end__, /* Top of Stack */ (int)&Reset_Handler, /* Reset Handler */ (int)&NMI_Handler, /* NMI Handler */ (int)&HardFault_Handler, /* Hard Fault Handler */ (int)&MemManage_Handler, /* The MPU fault handler */ (int)&BusFault_Handler, /* The bus fault handler */ (int)&UsageFault_Handler, /* The usage fault handler */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&SVC_Handler, /* SVCall handler */ (int)&DebugMon_Handler, /* Debug monitor handler */ (int)&Default_Handler, /* Reserved */ (int)&PendSV_Handler, /* The PendSV handler */ (int)&SysTick_Handler, /* The SysTick handler */ /* pad the initial VT to the total size of 256B */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Relocated Vector Table beyond the 256B region around address 0. * That region is used for NULL-pointer protection by the MPU. */ (int)&__stack_end__, /* Top of Stack */ (int)&Reset_Handler, /* Reset Handler */ (int)&NMI_Handler, /* NMI Handler */ (int)&HardFault_Handler, /* Hard Fault Handler */ (int)&MemManage_Handler, /* The MPU fault handler */ (int)&BusFault_Handler, /* The bus fault handler */ (int)&UsageFault_Handler, /* The usage fault handler */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&SVC_Handler, /* SVCall handler */ (int)&DebugMon_Handler, /* Debug monitor handler */ (int)&Default_Handler, /* Reserved */ (int)&PendSV_Handler, /* The PendSV handler */ (int)&SysTick_Handler, /* The SysTick handler */ /*IRQ handlers... */ (int)&GPIOPortA_IRQHandler, /* GPIO Port A */ (int)&GPIOPortB_IRQHandler, /* GPIO Port B */ (int)&GPIOPortC_IRQHandler, /* GPIO Port C */ (int)&GPIOPortD_IRQHandler, /* GPIO Port D */ (int)&GPIOPortE_IRQHandler, /* GPIO Port E */ (int)&UART0_IRQHandler, /* UART0 Rx and Tx */ (int)&UART1_IRQHandler, /* UART1 Rx and Tx */ (int)&SSI0_IRQHandler, /* SSI0 Rx and Tx */ (int)&I2C0_IRQHandler, /* I2C0 Master and Slave */ (int)&PWMFault_IRQHandler, /* PWM Fault */ (int)&PWMGen0_IRQHandler, /* PWM Generator 0 */ (int)&PWMGen1_IRQHandler, /* PWM Generator 1 */ (int)&PWMGen2_IRQHandler, /* PWM Generator 2 */ (int)&QEI0_IRQHandler, /* Quadrature Encoder 0 */ (int)&ADCSeq0_IRQHandler, /* ADC Sequence 0 */ (int)&ADCSeq1_IRQHandler, /* ADC Sequence 1 */ (int)&ADCSeq2_IRQHandler, /* ADC Sequence 2 */ (int)&ADCSeq3_IRQHandler, /* ADC Sequence 3 */ (int)&Watchdog_IRQHandler, /* Watchdog timer */ (int)&Timer0A_IRQHandler, /* Timer 0 subtimer A */ (int)&Timer0B_IRQHandler, /* Timer 0 subtimer B */ (int)&Timer1A_IRQHandler, /* Timer 1 subtimer A */ (int)&Timer1B_IRQHandler, /* Timer 1 subtimer B */ (int)&Timer2A_IRQHandler, /* Timer 2 subtimer A */ (int)&Timer2B_IRQHandler, /* Timer 2 subtimer B */ (int)&Comp0_IRQHandler, /* Analog Comparator 0 */ (int)&Comp1_IRQHandler, /* Analog Comparator 1 */ (int)&Comp2_IRQHandler, /* Analog Comparator 2 */ (int)&SysCtrl_IRQHandler, /* System Control (PLL, OSC, BO) */ (int)&FlashCtrl_IRQHandler, /* FLASH Control */ (int)&GPIOPortF_IRQHandler, /* GPIO Port F */ (int)&GPIOPortG_IRQHandler, /* GPIO Port G */ (int)&GPIOPortH_IRQHandler, /* GPIO Port H */ (int)&UART2_IRQHandler, /* UART2 Rx and Tx */ (int)&SSI1_IRQHandler, /* SSI1 Rx and Tx */ (int)&Timer3A_IRQHandler, /* Timer 3 subtimer A */ (int)&Timer3B_IRQHandler, /* Timer 3 subtimer B */ (int)&I2C1_IRQHandler, /* I2C1 Master and Slave */ (int)&QEI1_IRQHandler, /* Quadrature Encoder 1 */ (int)&CAN0_IRQHandler, /* CAN0 */ (int)&CAN1_IRQHandler, /* CAN1 */ (int)&CAN2_IRQHandler, /* CAN2 */ (int)&Default_Handler, /* Reserved */ (int)&Hibernate_IRQHandler, /* Hibernate */ (int)&USB0_IRQHandler, /* USB0 */ (int)&PWMGen3_IRQHandler, /* PWM Generator 3 */ (int)&uDMAST_IRQHandler, /* uDMA Software Transfer */ (int)&uDMAError_IRQHandler, /* uDMA Error */ (int)&ADC1Seq0_IRQHandler, /* ADC1 Sequence 0 */ (int)&ADC1Seq1_IRQHandler, /* ADC1 Sequence 1 */ (int)&ADC1Seq2_IRQHandler, /* ADC1 Sequence 2 */ (int)&ADC1Seq3_IRQHandler, /* ADC1 Sequence 3 */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&GPIOPortJ_IRQHandler, /* GPIO Port J */ (int)&GPIOPortK_IRQHandler, /* GPIO Port K */ (int)&GPIOPortL_IRQHandler, /* GPIO Port L */ (int)&SSI2_IRQHandler, /* SSI2 Rx and Tx */ (int)&SSI3_IRQHandler, /* SSI3 Rx and Tx */ (int)&UART3_IRQHandler, /* UART3 Rx and Tx */ (int)&UART4_IRQHandler, /* UART4 Rx and Tx */ (int)&UART5_IRQHandler, /* UART5 Rx and Tx */ (int)&UART6_IRQHandler, /* UART6 Rx and Tx */ (int)&UART7_IRQHandler, /* UART7 Rx and Tx */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&I2C2_IRQHandler, /* I2C2 Master and Slave */ (int)&I2C3_IRQHandler, /* I2C3 Master and Slave */ (int)&Timer4A_IRQHandler, /* Timer 4 subtimer A */ (int)&Timer4B_IRQHandler, /* Timer 4 subtimer B */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Timer5A_IRQHandler, /* Timer 5 subtimer A */ (int)&Timer5B_IRQHandler, /* Timer 5 subtimer B */ (int)&WideTimer0A_IRQHandler, /* Wide Timer 0 subtimer A */ (int)&WideTimer0B_IRQHandler, /* Wide Timer 0 subtimer B */ (int)&WideTimer1A_IRQHandler, /* Wide Timer 1 subtimer A */ (int)&WideTimer1B_IRQHandler, /* Wide Timer 1 subtimer B */ (int)&WideTimer2A_IRQHandler, /* Wide Timer 2 subtimer A */ (int)&WideTimer2B_IRQHandler, /* Wide Timer 2 subtimer B */ (int)&WideTimer3A_IRQHandler, /* Wide Timer 3 subtimer A */ (int)&WideTimer3B_IRQHandler, /* Wide Timer 3 subtimer B */ (int)&WideTimer4A_IRQHandler, /* Wide Timer 4 subtimer A */ (int)&WideTimer4B_IRQHandler, /* Wide Timer 4 subtimer B */ (int)&WideTimer5A_IRQHandler, /* Wide Timer 5 subtimer A */ (int)&WideTimer5B_IRQHandler, /* Wide Timer 5 subtimer B */ (int)&FPU_IRQHandler, /* FPU */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&I2C4_IRQHandler, /* I2C4 Master and Slave */ (int)&I2C5_IRQHandler, /* I2C5 Master and Slave */ (int)&GPIOPortM_IRQHandler, /* GPIO Port M */ (int)&GPIOPortN_IRQHandler, /* GPIO Port N */ (int)&QEI2_IRQHandler, /* Quadrature Encoder 2 */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&GPIOPortP0_IRQHandler, /* GPIO Port P (Summary or P0) */ (int)&GPIOPortP1_IRQHandler, /* GPIO Port P1 */ (int)&GPIOPortP2_IRQHandler, /* GPIO Port P2 */ (int)&GPIOPortP3_IRQHandler, /* GPIO Port P3 */ (int)&GPIOPortP4_IRQHandler, /* GPIO Port P4 */ (int)&GPIOPortP5_IRQHandler, /* GPIO Port P5 */ (int)&GPIOPortP6_IRQHandler, /* GPIO Port P6 */ (int)&GPIOPortP7_IRQHandler, /* GPIO Port P7 */ (int)&GPIOPortQ0_IRQHandler, /* GPIO Port Q (Summary or Q0) */ (int)&GPIOPortQ1_IRQHandler, /* GPIO Port Q1 */ (int)&GPIOPortQ2_IRQHandler, /* GPIO Port Q2 */ (int)&GPIOPortQ3_IRQHandler, /* GPIO Port Q3 */ (int)&GPIOPortQ4_IRQHandler, /* GPIO Port Q4 */ (int)&GPIOPortQ5_IRQHandler, /* GPIO Port Q5 */ (int)&GPIOPortQ6_IRQHandler, /* GPIO Port Q6 */ (int)&GPIOPortQ7_IRQHandler, /* GPIO Port Q7 */ (int)&GPIOPortR_IRQHandler, /* GPIO Port R */ (int)&GPIOPortS_IRQHandler, /* GPIO Port S */ (int)&PWM1Gen0_IRQHandler, /* PWM 1 Generator 0 */ (int)&PWM1Gen1_IRQHandler, /* PWM 1 Generator 1 */ (int)&PWM1Gen2_IRQHandler, /* PWM 1 Generator 2 */ (int)&PWM1Gen3_IRQHandler, /* PWM 1 Generator 3 */ (int)&PWM1Fault_IRQHandler, /* PWM 1 Fault */ }; /* reset handler -----------------------------------------------------------*/ __attribute__((naked)) void Reset_Handler(void); void Reset_Handler(void) { extern int main(void); extern int __libc_init_array(void); extern unsigned __data_start; /* start of .data in the linker script */ extern unsigned __data_end__; /* end of .data in the linker script */ extern unsigned const __data_load; /* initialization values for .data */ extern unsigned __bss_start__; /* start of .bss in the linker script */ extern unsigned __bss_end__; /* end of .bss in the linker script */ extern void software_init_hook(void) __attribute__((weak)); /* relocate the Vector Table to leave room for the NULL-pointer region * System Control Block/Vector Table Offset Reg := relocated Vector Table */ *(int const * volatile *)0xE000ED08 = &g_pfnVectors[256/sizeof(int)]; SystemInit(); /* CMSIS system initialization */ /* copy the data segment initializers from flash to RAM... */ unsigned const *src = &__data_load; unsigned *dst; for (dst = &__data_start; dst < &__data_end__; ++dst, ++src) { *dst = *src; } /* zero fill the .bss segment in RAM... */ for (dst = &__bss_start__; dst < &__bss_end__; ++dst) { *dst = 0; } /* init hook provided? */ if (&software_init_hook != (void (*)(void))(0)) { /* give control to the RTOS */ software_init_hook(); /* this will also call __libc_init_array */ } else { /* call all static constructors in C++ (harmless in C programs) */ __libc_init_array(); (void)main(); /* application's entry point; should never return! */ } /* the previous code should not return, but assert just in case... */ assert_failed("Reset_Handler", 1U); } /* fault exception handlers ------------------------------------------------*/ __attribute__((naked)) void NMI_Handler(void); void NMI_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("NMI_Handler", 1U); } /*..........................................................................*/ __attribute__((naked)) void HardFault_Handler(void); void HardFault_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("HardFault_Handler", 1U); } /*..........................................................................*/ __attribute__((naked)) void MemManage_Handler(void); void MemManage_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("MemManage_Handler", 1U); } /*..........................................................................*/ __attribute__((naked)) void BusFault_Handler(void); void BusFault_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("MemManage_Handler", 1U); } /*..........................................................................*/ __attribute__((naked)) void UsageFault_Handler(void); void UsageFault_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("BusFault_Handler", 1U); } /*..........................................................................*/ __attribute__((naked)) void Default_Handler(void); void Default_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("Default_Handler", 1U); } ================================================ FILE: 3rd_party/ek-tm4c123gxl/gpio.h ================================================ //============================================================================* // // gpio.h - Defines and Macros for GPIO API. // // Copyright (c) 2005-2015 Texas Instruments Incorporated. All rights reserved. // Software License Agreement // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // This is part of revision 2.1.2.111 of the Tiva Peripheral Driver Library. // //============================================================================* #ifndef __DRIVERLIB_GPIO_H__ #define __DRIVERLIB_GPIO_H__ //============================================================================* // // If building with a C++ compiler, make all of the definitions in this header // have a C binding. // //============================================================================* #ifdef __cplusplus extern "C" { #endif //============================================================================* // // The following values define the bit field for the ui8Pins argument to // several of the APIs. // //============================================================================* #define GPIO_PIN_0 0x00000001 // GPIO pin 0 #define GPIO_PIN_1 0x00000002 // GPIO pin 1 #define GPIO_PIN_2 0x00000004 // GPIO pin 2 #define GPIO_PIN_3 0x00000008 // GPIO pin 3 #define GPIO_PIN_4 0x00000010 // GPIO pin 4 #define GPIO_PIN_5 0x00000020 // GPIO pin 5 #define GPIO_PIN_6 0x00000040 // GPIO pin 6 #define GPIO_PIN_7 0x00000080 // GPIO pin 7 //============================================================================* // // Values that can be passed to GPIODirModeSet as the ui32PinIO parameter, and // returned from GPIODirModeGet. // //============================================================================* #define GPIO_DIR_MODE_IN 0x00000000 // Pin is a GPIO input #define GPIO_DIR_MODE_OUT 0x00000001 // Pin is a GPIO output #define GPIO_DIR_MODE_HW 0x00000002 // Pin is a peripheral function //============================================================================* // // Values that can be passed to GPIOIntTypeSet as the ui32IntType parameter, // and returned from GPIOIntTypeGet. // //============================================================================* #define GPIO_FALLING_EDGE 0x00000000 // Interrupt on falling edge #define GPIO_RISING_EDGE 0x00000004 // Interrupt on rising edge #define GPIO_BOTH_EDGES 0x00000001 // Interrupt on both edges #define GPIO_LOW_LEVEL 0x00000002 // Interrupt on low level #define GPIO_HIGH_LEVEL 0x00000006 // Interrupt on high level #define GPIO_DISCRETE_INT 0x00010000 // Interrupt for individual pins //============================================================================* // // Values that can be passed to GPIOPadConfigSet as the ui32Strength parameter, // and returned by GPIOPadConfigGet in the *pui32Strength parameter. // //============================================================================* #define GPIO_STRENGTH_2MA 0x00000001 // 2mA drive strength #define GPIO_STRENGTH_4MA 0x00000002 // 4mA drive strength #define GPIO_STRENGTH_6MA 0x00000065 // 6mA drive strength #define GPIO_STRENGTH_8MA 0x00000066 // 8mA drive strength #define GPIO_STRENGTH_8MA_SC 0x0000006E // 8mA drive with slew rate control #define GPIO_STRENGTH_10MA 0x00000075 // 10mA drive strength #define GPIO_STRENGTH_12MA 0x00000077 // 12mA drive strength //============================================================================* // // Values that can be passed to GPIOPadConfigSet as the ui32PadType parameter, // and returned by GPIOPadConfigGet in the *pui32PadType parameter. // //============================================================================* #define GPIO_PIN_TYPE_STD 0x00000008 // Push-pull #define GPIO_PIN_TYPE_STD_WPU 0x0000000A // Push-pull with weak pull-up #define GPIO_PIN_TYPE_STD_WPD 0x0000000C // Push-pull with weak pull-down #define GPIO_PIN_TYPE_OD 0x00000009 // Open-drain #define GPIO_PIN_TYPE_ANALOG 0x00000000 // Analog comparator #define GPIO_PIN_TYPE_WAKE_HIGH 0x00000208 // Hibernate wake, high #define GPIO_PIN_TYPE_WAKE_LOW 0x00000108 // Hibernate wake, low //============================================================================* // // Values that can be passed to GPIOIntEnable() and GPIOIntDisable() functions // in the ui32IntFlags parameter. // //============================================================================* #define GPIO_INT_PIN_0 0x00000001 #define GPIO_INT_PIN_1 0x00000002 #define GPIO_INT_PIN_2 0x00000004 #define GPIO_INT_PIN_3 0x00000008 #define GPIO_INT_PIN_4 0x00000010 #define GPIO_INT_PIN_5 0x00000020 #define GPIO_INT_PIN_6 0x00000040 #define GPIO_INT_PIN_7 0x00000080 #define GPIO_INT_DMA 0x00000100 //============================================================================* // // Prototypes for the APIs. // //============================================================================* extern void GPIODirModeSet(uint32_t ui32Port, uint8_t ui8Pins, uint32_t ui32PinIO); extern uint32_t GPIODirModeGet(uint32_t ui32Port, uint8_t ui8Pin); extern void GPIOIntTypeSet(uint32_t ui32Port, uint8_t ui8Pins, uint32_t ui32IntType); extern uint32_t GPIOIntTypeGet(uint32_t ui32Port, uint8_t ui8Pin); extern void GPIOPadConfigSet(uint32_t ui32Port, uint8_t ui8Pins, uint32_t ui32Strength, uint32_t ui32PadType); extern void GPIOPadConfigGet(uint32_t ui32Port, uint8_t ui8Pin, uint32_t *pui32Strength, uint32_t *pui32PadType); extern void GPIOIntEnable(uint32_t ui32Port, uint32_t ui32IntFlags); extern void GPIOIntDisable(uint32_t ui32Port, uint32_t ui32IntFlags); extern uint32_t GPIOIntStatus(uint32_t ui32Port, bool bMasked); extern void GPIOIntClear(uint32_t ui32Port, uint32_t ui32IntFlags); extern void GPIOIntRegister(uint32_t ui32Port, void (*pfnIntHandler)(void)); extern void GPIOIntUnregister(uint32_t ui32Port); extern int32_t GPIOPinRead(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinWrite(uint32_t ui32Port, uint8_t ui8Pins, uint8_t ui8Val); extern void GPIOPinConfigure(uint32_t ui32PinConfig); extern void GPIOPinTypeADC(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeCAN(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeComparator(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeComparatorOutput(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeDIVSCLK(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeEPI(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeEthernetLED(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeEthernetMII(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeGPIOInput(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeGPIOOutput(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeGPIOOutputOD(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeHibernateRTCCLK(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeI2C(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeI2CSCL(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeLCD(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeOneWire(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypePWM(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeQEI(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeSSI(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeTimer(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeTrace(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeUART(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeUSBAnalog(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeUSBDigital(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeWakeHigh(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOPinTypeWakeLow(uint32_t ui32Port, uint8_t ui8Pins); extern uint32_t GPIOPinWakeStatus(uint32_t ui32Port); extern void GPIODMATriggerEnable(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIODMATriggerDisable(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOADCTriggerEnable(uint32_t ui32Port, uint8_t ui8Pins); extern void GPIOADCTriggerDisable(uint32_t ui32Port, uint8_t ui8Pins); //============================================================================* // // Mark the end of the C bindings section for C++ compilers. // //============================================================================* #ifdef __cplusplus } #endif #endif // __DRIVERLIB_GPIO_H__ ================================================ FILE: 3rd_party/ek-tm4c123gxl/iar/startup_TM4C123GH6PM.s ================================================ ;/***************************************************************************/ ; * @file startup_TM4C123GH6PM.s for IAR ARM assembler ; * @brief CMSIS Cortex-M4F Core Device Startup File for TM4C123GH6PM ; * @version CMSIS 5.9.0 ; * @date 1 Feb 2023 ; * ; * Modified by Quantum Leaps: ; * - Added relocating of the Vector Table to free up the 256B region at 0x0 ; * for NULL-pointer protection by the MPU. ; * - Modified all exception handlers to branch to assert_failed() ; * instead of locking up the CPU inside an endless loop. ; * ; * @description ; * Created from the CMSIS template for the specified device ; * Quantum Leaps, www.state-machine.com ; * MODULE ?cstartup ; Forward declaration of sections. SECTION CSTACK:DATA:NOROOT(3) SECTION .intvec:CODE:NOROOT(8) PUBLIC __vector_table PUBLIC __Vectors PUBLIC __Vectors_End PUBLIC __Vectors_Size ;****************************************************************************** ; The vector table. ; DATA __vector_table ; Initial Vector Table before relocation DCD sfe(CSTACK) DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU fault handler DCD BusFault_Handler ; Bus fault handler DCD UsageFault_Handler ; Usage fault handler DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD SVC_Handler ; SVCall handler DCD DebugMon_Handler ; Debug Monitor handler DCD Default_Handler ; Reserved DCD PendSV_Handler ; PendSV handler DCD SysTick_Handler ; SysTick handler ALIGNROM 8 ; Extend the initial Vector Table to the 2^8==256B ; Relocated Vector Table beyond the 256B region around address 0. ; That region is used for NULL-pointer protection by the MPU. __relocated_vector_table DCD sfe(CSTACK) DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU fault handler DCD BusFault_Handler ; Bus fault handler DCD UsageFault_Handler ; Usage fault handler DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD SVC_Handler ; SVCall handler DCD DebugMon_Handler ; Debug Monitor handler DCD Default_Handler ; Reserved DCD PendSV_Handler ; PendSV handler DCD SysTick_Handler ; SysTick handler ; IRQ handlers... DCD GPIOPortA_IRQHandler ; GPIO Port A DCD GPIOPortB_IRQHandler ; GPIO Port B DCD GPIOPortC_IRQHandler ; GPIO Port C DCD GPIOPortD_IRQHandler ; GPIO Port D DCD GPIOPortE_IRQHandler ; GPIO Port E DCD UART0_IRQHandler ; UART0 Rx and Tx DCD UART1_IRQHandler ; UART1 Rx and Tx DCD SSI0_IRQHandler ; SSI0 Rx and Tx DCD I2C0_IRQHandler ; I2C0 Master and Slave DCD PWMFault_IRQHandler ; PWM Fault DCD PWMGen0_IRQHandler ; PWM Generator 0 DCD PWMGen1_IRQHandler ; PWM Generator 1 DCD PWMGen2_IRQHandler ; PWM Generator 2 DCD QEI0_IRQHandler ; Quadrature Encoder 0 DCD ADCSeq0_IRQHandler ; ADC Sequence 0 DCD ADCSeq1_IRQHandler ; ADC Sequence 1 DCD ADCSeq2_IRQHandler ; ADC Sequence 2 DCD ADCSeq3_IRQHandler ; ADC Sequence 3 DCD Watchdog_IRQHandler ; Watchdog timer DCD Timer0A_IRQHandler ; Timer 0 subtimer A DCD Timer0B_IRQHandler ; Timer 0 subtimer B DCD Timer1A_IRQHandler ; Timer 1 subtimer A DCD Timer1B_IRQHandler ; Timer 1 subtimer B DCD Timer2A_IRQHandler ; Timer 2 subtimer A DCD Timer2B_IRQHandler ; Timer 2 subtimer B DCD Comp0_IRQHandler ; Analog Comparator 0 DCD Comp1_IRQHandler ; Analog Comparator 1 DCD Comp2_IRQHandler ; Analog Comparator 2 DCD SysCtrl_IRQHandler ; System Control (PLL, OSC, BO) DCD FlashCtrl_IRQHandler ; FLASH Control DCD GPIOPortF_IRQHandler ; GPIO Port F DCD GPIOPortG_IRQHandler ; GPIO Port G DCD GPIOPortH_IRQHandler ; GPIO Port H DCD UART2_IRQHandler ; UART2 Rx and Tx DCD SSI1_IRQHandler ; SSI1 Rx and Tx DCD Timer3A_IRQHandler ; Timer 3 subtimer A DCD Timer3B_IRQHandler ; Timer 3 subtimer B DCD I2C1_IRQHandler ; I2C1 Master and Slave DCD QEI1_IRQHandler ; Quadrature Encoder 1 DCD CAN0_IRQHandler ; CAN0 DCD CAN1_IRQHandler ; CAN1 DCD CAN2_IRQHandler ; CAN2 DCD Default_Handler ; Reserved DCD Hibernate_IRQHandler ; Hibernate DCD USB0_IRQHandler ; USB0 DCD PWMGen3_IRQHandler ; PWM Generator 3 DCD uDMAST_IRQHandler ; uDMA Software Transfer DCD uDMAError_IRQHandler ; uDMA Error DCD ADC1Seq0_IRQHandler ; ADC1 Sequence 0 DCD ADC1Seq1_IRQHandler ; ADC1 Sequence 1 DCD ADC1Seq2_IRQHandler ; ADC1 Sequence 2 DCD ADC1Seq3_IRQHandler ; ADC1 Sequence 3 DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD GPIOPortJ_IRQHandler ; GPIO Port J DCD GPIOPortK_IRQHandler ; GPIO Port K DCD GPIOPortL_IRQHandler ; GPIO Port L DCD SSI2_IRQHandler ; SSI2 Rx and Tx DCD SSI3_IRQHandler ; SSI3 Rx and Tx DCD UART3_IRQHandler ; UART3 Rx and Tx DCD UART4_IRQHandler ; UART4 Rx and Tx DCD UART5_IRQHandler ; UART5 Rx and Tx DCD UART6_IRQHandler ; UART6 Rx and Tx DCD UART7_IRQHandler ; UART7 Rx and Tx DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD I2C2_IRQHandler ; I2C2 Master and Slave DCD I2C3_IRQHandler ; I2C3 Master and Slave DCD Timer4A_IRQHandler ; Timer 4 subtimer A DCD Timer4B_IRQHandler ; Timer 4 subtimer B DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Timer5A_IRQHandler ; Timer 5 subtimer A DCD Timer5B_IRQHandler ; Timer 5 subtimer B DCD WideTimer0A_IRQHandler ; Wide Timer 0 subtimer A DCD WideTimer0B_IRQHandler ; Wide Timer 0 subtimer B DCD WideTimer1A_IRQHandler ; Wide Timer 1 subtimer A DCD WideTimer1B_IRQHandler ; Wide Timer 1 subtimer B DCD WideTimer2A_IRQHandler ; Wide Timer 2 subtimer A DCD WideTimer2B_IRQHandler ; Wide Timer 2 subtimer B DCD WideTimer3A_IRQHandler ; Wide Timer 3 subtimer A DCD WideTimer3B_IRQHandler ; Wide Timer 3 subtimer B DCD WideTimer4A_IRQHandler ; Wide Timer 4 subtimer A DCD WideTimer4B_IRQHandler ; Wide Timer 4 subtimer B DCD WideTimer5A_IRQHandler ; Wide Timer 5 subtimer A DCD WideTimer5B_IRQHandler ; Wide Timer 5 subtimer B DCD FPU_IRQHandler ; FPU DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD I2C4_IRQHandler ; I2C4 Master and Slave DCD I2C5_IRQHandler ; I2C5 Master and Slave DCD GPIOPortM_IRQHandler ; GPIO Port M DCD GPIOPortN_IRQHandler ; GPIO Port N DCD QEI2_IRQHandler ; Quadrature Encoder 2 DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD GPIOPortP0_IRQHandler ; GPIO Port P (Summary or P0) DCD GPIOPortP1_IRQHandler ; GPIO Port P1 DCD GPIOPortP2_IRQHandler ; GPIO Port P2 DCD GPIOPortP3_IRQHandler ; GPIO Port P3 DCD GPIOPortP4_IRQHandler ; GPIO Port P4 DCD GPIOPortP5_IRQHandler ; GPIO Port P5 DCD GPIOPortP6_IRQHandler ; GPIO Port P6 DCD GPIOPortP7_IRQHandler ; GPIO Port P7 DCD GPIOPortQ0_IRQHandler ; GPIO Port Q (Summary or Q0) DCD GPIOPortQ1_IRQHandler ; GPIO Port Q1 DCD GPIOPortQ2_IRQHandler ; GPIO Port Q2 DCD GPIOPortQ3_IRQHandler ; GPIO Port Q3 DCD GPIOPortQ4_IRQHandler ; GPIO Port Q4 DCD GPIOPortQ5_IRQHandler ; GPIO Port Q5 DCD GPIOPortQ6_IRQHandler ; GPIO Port Q6 DCD GPIOPortQ7_IRQHandler ; GPIO Port Q7 DCD GPIOPortR_IRQHandler ; GPIO Port R DCD GPIOPortS_IRQHandler ; GPIO Port S DCD PWM1Gen0_IRQHandler ; PWM 1 Generator 0 DCD PWM1Gen1_IRQHandler ; PWM 1 Generator 1 DCD PWM1Gen2_IRQHandler ; PWM 1 Generator 2 DCD PWM1Gen3_IRQHandler ; PWM 1 Generator 3 DCD PWM1Fault_IRQHandler ; PWM 1 Fault __Vectors_End __Vectors EQU __vector_table __Vectors_Size EQU __Vectors_End - __Vectors ;****************************************************************************** ; This is the code for exception handlers. ; SECTION .text:CODE:REORDER:NOROOT(2) ;****************************************************************************** ; This is the code that gets called when theessor first starts execution ; following a reset event. ; PUBWEAK Reset_Handler EXTERN SystemInit EXTERN __iar_program_start EXTERN assert_failed Reset_Handler ; relocate the Vector Table LDR r0,=0xE000ED08 ; System Control Block/Vector Table Offset Reg LDR r1,=__relocated_vector_table STR r1,[r0] ; SCB->VTOR := __relocated_vector_table LDR r0,=SystemInit ; CMSIS system initialization BLX r0 ; pre-fill the CSTACK with 0xDEADBEEF................... LDR r0,=0xDEADBEEF MOV r1,r0 LDR r2,=sfb(CSTACK) LDR r3,=sfe(CSTACK) Reset_stackInit_fill: STMIA r2!,{r0,r1} CMP r2,r3 BLT.N Reset_stackInit_fill LDR r0,=__iar_program_start ; IAR startup code BLX r0 ; __iar_program_start calls the main() function, which should not return, ; but just in case jump to assert_failed() if main returns. LDR r0,=str_EXIT MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_EXIT DCB "EXIT" ALIGNROM 2 ;****************************************************************************** PUBWEAK NMI_Handler NMI_Handler LDR r0,=str_NMI MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_NMI DCB "NMI" ALIGNROM 2 ;****************************************************************************** PUBWEAK HardFault_Handler HardFault_Handler LDR r0,=str_HardFault MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_HardFault DCB "HardFault" ALIGNROM 2 ;****************************************************************************** PUBWEAK MemManage_Handler MemManage_Handler LDR r0,=str_MemManage MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_MemManage DCB "MemManage" ALIGNROM 2 ;****************************************************************************** PUBWEAK BusFault_Handler BusFault_Handler LDR r0,=str_BusFault MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_BusFault DCB "BusFault" ALIGNROM 2 ;****************************************************************************** PUBWEAK UsageFault_Handler UsageFault_Handler LDR r0,=str_UsageFault MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_UsageFault DCB "UsageFault" ALIGNROM 2 ;****************************************************************************** ; ; Weak non-fault handlers... ; ;****************************************************************************** PUBWEAK SVC_Handler SVC_Handler LDR r0,=str_SVC MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_SVC DCB "SVC" ALIGNROM 2 ;****************************************************************************** PUBWEAK DebugMon_Handler DebugMon_Handler LDR r0,=str_DebugMon MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_DebugMon DCB "DebugMon" ALIGNROM 2 ;****************************************************************************** PUBWEAK PendSV_Handler PendSV_Handler LDR r0,=str_PendSV MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_PendSV DCB "PendSV" ALIGNROM 2 ;****************************************************************************** PUBWEAK SysTick_Handler SysTick_Handler LDR r0,=str_SysTick MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_SysTick DCB "SysTick" ALIGNROM 2 ;****************************************************************************** ; Weak IRQ handlers... ; PUBWEAK Default_Handler PUBWEAK GPIOPortA_IRQHandler PUBWEAK GPIOPortB_IRQHandler PUBWEAK GPIOPortC_IRQHandler PUBWEAK GPIOPortD_IRQHandler PUBWEAK GPIOPortE_IRQHandler PUBWEAK UART0_IRQHandler PUBWEAK UART1_IRQHandler PUBWEAK SSI0_IRQHandler PUBWEAK I2C0_IRQHandler PUBWEAK PWMFault_IRQHandler PUBWEAK PWMGen0_IRQHandler PUBWEAK PWMGen1_IRQHandler PUBWEAK PWMGen2_IRQHandler PUBWEAK QEI0_IRQHandler PUBWEAK ADCSeq0_IRQHandler PUBWEAK ADCSeq1_IRQHandler PUBWEAK ADCSeq2_IRQHandler PUBWEAK ADCSeq3_IRQHandler PUBWEAK Watchdog_IRQHandler PUBWEAK Timer0A_IRQHandler PUBWEAK Timer0B_IRQHandler PUBWEAK Timer1A_IRQHandler PUBWEAK Timer1B_IRQHandler PUBWEAK Timer2A_IRQHandler PUBWEAK Timer2B_IRQHandler PUBWEAK Comp0_IRQHandler PUBWEAK Comp1_IRQHandler PUBWEAK Comp2_IRQHandler PUBWEAK SysCtrl_IRQHandler PUBWEAK FlashCtrl_IRQHandler PUBWEAK GPIOPortF_IRQHandler PUBWEAK GPIOPortG_IRQHandler PUBWEAK GPIOPortH_IRQHandler PUBWEAK UART2_IRQHandler PUBWEAK SSI1_IRQHandler PUBWEAK Timer3A_IRQHandler PUBWEAK Timer3B_IRQHandler PUBWEAK I2C1_IRQHandler PUBWEAK QEI1_IRQHandler PUBWEAK CAN0_IRQHandler PUBWEAK CAN1_IRQHandler PUBWEAK CAN2_IRQHandler PUBWEAK Hibernate_IRQHandler PUBWEAK USB0_IRQHandler PUBWEAK PWMGen3_IRQHandler PUBWEAK uDMAST_IRQHandler PUBWEAK uDMAError_IRQHandler PUBWEAK ADC1Seq0_IRQHandler PUBWEAK ADC1Seq1_IRQHandler PUBWEAK ADC1Seq2_IRQHandler PUBWEAK ADC1Seq3_IRQHandler PUBWEAK GPIOPortJ_IRQHandler PUBWEAK GPIOPortK_IRQHandler PUBWEAK GPIOPortL_IRQHandler PUBWEAK SSI2_IRQHandler PUBWEAK SSI3_IRQHandler PUBWEAK UART3_IRQHandler PUBWEAK UART4_IRQHandler PUBWEAK UART5_IRQHandler PUBWEAK UART6_IRQHandler PUBWEAK UART7_IRQHandler PUBWEAK I2C2_IRQHandler PUBWEAK I2C3_IRQHandler PUBWEAK Timer4A_IRQHandler PUBWEAK Timer4B_IRQHandler PUBWEAK Timer5A_IRQHandler PUBWEAK Timer5B_IRQHandler PUBWEAK WideTimer0A_IRQHandler PUBWEAK WideTimer0B_IRQHandler PUBWEAK WideTimer1A_IRQHandler PUBWEAK WideTimer1B_IRQHandler PUBWEAK WideTimer2A_IRQHandler PUBWEAK WideTimer2B_IRQHandler PUBWEAK WideTimer3A_IRQHandler PUBWEAK WideTimer3B_IRQHandler PUBWEAK WideTimer4A_IRQHandler PUBWEAK WideTimer4B_IRQHandler PUBWEAK WideTimer5A_IRQHandler PUBWEAK WideTimer5B_IRQHandler PUBWEAK FPU_IRQHandler PUBWEAK I2C4_IRQHandler PUBWEAK I2C5_IRQHandler PUBWEAK GPIOPortM_IRQHandler PUBWEAK GPIOPortN_IRQHandler PUBWEAK QEI2_IRQHandler PUBWEAK GPIOPortP0_IRQHandler PUBWEAK GPIOPortP1_IRQHandler PUBWEAK GPIOPortP2_IRQHandler PUBWEAK GPIOPortP3_IRQHandler PUBWEAK GPIOPortP4_IRQHandler PUBWEAK GPIOPortP5_IRQHandler PUBWEAK GPIOPortP6_IRQHandler PUBWEAK GPIOPortP7_IRQHandler PUBWEAK GPIOPortQ0_IRQHandler PUBWEAK GPIOPortQ1_IRQHandler PUBWEAK GPIOPortQ2_IRQHandler PUBWEAK GPIOPortQ3_IRQHandler PUBWEAK GPIOPortQ4_IRQHandler PUBWEAK GPIOPortQ5_IRQHandler PUBWEAK GPIOPortQ6_IRQHandler PUBWEAK GPIOPortQ7_IRQHandler PUBWEAK GPIOPortR_IRQHandler PUBWEAK GPIOPortS_IRQHandler PUBWEAK PWM1Gen0_IRQHandler PUBWEAK PWM1Gen1_IRQHandler PUBWEAK PWM1Gen2_IRQHandler PUBWEAK PWM1Gen3_IRQHandler PUBWEAK PWM1Fault_IRQHandler Default_Handler GPIOPortA_IRQHandler GPIOPortB_IRQHandler GPIOPortC_IRQHandler GPIOPortD_IRQHandler GPIOPortE_IRQHandler UART0_IRQHandler UART1_IRQHandler SSI0_IRQHandler I2C0_IRQHandler PWMFault_IRQHandler PWMGen0_IRQHandler PWMGen1_IRQHandler PWMGen2_IRQHandler QEI0_IRQHandler ADCSeq0_IRQHandler ADCSeq1_IRQHandler ADCSeq2_IRQHandler ADCSeq3_IRQHandler Watchdog_IRQHandler Timer0A_IRQHandler Timer0B_IRQHandler Timer1A_IRQHandler Timer1B_IRQHandler Timer2A_IRQHandler Timer2B_IRQHandler Comp0_IRQHandler Comp1_IRQHandler Comp2_IRQHandler SysCtrl_IRQHandler FlashCtrl_IRQHandler GPIOPortF_IRQHandler GPIOPortG_IRQHandler GPIOPortH_IRQHandler UART2_IRQHandler SSI1_IRQHandler Timer3A_IRQHandler Timer3B_IRQHandler I2C1_IRQHandler QEI1_IRQHandler CAN0_IRQHandler CAN1_IRQHandler CAN2_IRQHandler Hibernate_IRQHandler USB0_IRQHandler PWMGen3_IRQHandler uDMAST_IRQHandler uDMAError_IRQHandler ADC1Seq0_IRQHandler ADC1Seq1_IRQHandler ADC1Seq2_IRQHandler ADC1Seq3_IRQHandler GPIOPortJ_IRQHandler GPIOPortK_IRQHandler GPIOPortL_IRQHandler SSI2_IRQHandler SSI3_IRQHandler UART3_IRQHandler UART4_IRQHandler UART5_IRQHandler UART6_IRQHandler UART7_IRQHandler I2C2_IRQHandler I2C3_IRQHandler Timer4A_IRQHandler Timer4B_IRQHandler Timer5A_IRQHandler Timer5B_IRQHandler WideTimer0A_IRQHandler WideTimer0B_IRQHandler WideTimer1A_IRQHandler WideTimer1B_IRQHandler WideTimer2A_IRQHandler WideTimer2B_IRQHandler WideTimer3A_IRQHandler WideTimer3B_IRQHandler WideTimer4A_IRQHandler WideTimer4B_IRQHandler WideTimer5A_IRQHandler WideTimer5B_IRQHandler FPU_IRQHandler I2C4_IRQHandler I2C5_IRQHandler GPIOPortM_IRQHandler GPIOPortN_IRQHandler QEI2_IRQHandler GPIOPortP0_IRQHandler GPIOPortP1_IRQHandler GPIOPortP2_IRQHandler GPIOPortP3_IRQHandler GPIOPortP4_IRQHandler GPIOPortP5_IRQHandler GPIOPortP6_IRQHandler GPIOPortP7_IRQHandler GPIOPortQ0_IRQHandler GPIOPortQ1_IRQHandler GPIOPortQ2_IRQHandler GPIOPortQ3_IRQHandler GPIOPortQ4_IRQHandler GPIOPortQ5_IRQHandler GPIOPortQ6_IRQHandler GPIOPortQ7_IRQHandler GPIOPortR_IRQHandler GPIOPortS_IRQHandler PWM1Gen0_IRQHandler PWM1Gen1_IRQHandler PWM1Gen2_IRQHandler PWM1Gen3_IRQHandler PWM1Fault_IRQHandler LDR r0,=str_Undefined MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_Undefined DCB "Undefined" ALIGNROM 2 END ; end of module ================================================ FILE: 3rd_party/ek-tm4c123gxl/rom.h ================================================ //============================================================================* // // rom.h - Macros to facilitate calling functions in the ROM. // // Copyright (c) 2007-2015 Texas Instruments Incorporated. All rights reserved. // Software License Agreement // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // This is part of revision 2.1.2.111 of the Tiva Peripheral Driver Library. // //============================================================================* #ifndef __DRIVERLIB_ROM_H__ #define __DRIVERLIB_ROM_H__ #ifndef DEPRECATED //============================================================================* // // ROM selection labels changed between TivaWare 2.0.1 and 2.1. The following // labels are intended to ensure backwards compatibility for applications // which have not yet been updated to use the replacement labels. // //============================================================================* #ifdef TARGET_IS_SNOWFLAKE_RA0 #define TARGET_IS_TM4C129_RA0 #endif #ifdef TARGET_IS_SNOWFLAKE_RA1 #define TARGET_IS_TM4C129_RA1 #endif #ifdef TARGET_IS_SNOWFLAKE_RA2 #define TARGET_IS_TM4C129_RA2 #endif #ifdef TARGET_IS_BLIZZARD_RA1 #define TARGET_IS_TM4C123_RA1 #endif #ifdef TARGET_IS_BLIZZARD_RA2 #define TARGET_IS_TM4C123_RA2 #endif #ifdef TARGET_IS_BLIZZARD_RA3 #define TARGET_IS_TM4C123_RA3 #endif #ifdef TARGET_IS_BLIZZARD_RB0 #define TARGET_IS_TM4C123_RB0 #endif #ifdef TARGET_IS_BLIZZARD_RB1 #define TARGET_IS_TM4C123_RB1 #endif #endif //============================================================================* // // Pointers to the main API tables. // //============================================================================* #define ROM_APITABLE ((uint32_t *)0x01000010) #define ROM_VERSION (ROM_APITABLE[0]) #define ROM_UARTTABLE ((uint32_t *)(ROM_APITABLE[1])) #define ROM_SSITABLE ((uint32_t *)(ROM_APITABLE[2])) #define ROM_I2CTABLE ((uint32_t *)(ROM_APITABLE[3])) #define ROM_GPIOTABLE ((uint32_t *)(ROM_APITABLE[4])) #define ROM_ADCTABLE ((uint32_t *)(ROM_APITABLE[5])) #define ROM_COMPARATORTABLE ((uint32_t *)(ROM_APITABLE[6])) #define ROM_FLASHTABLE ((uint32_t *)(ROM_APITABLE[7])) #define ROM_PWMTABLE ((uint32_t *)(ROM_APITABLE[8])) #define ROM_QEITABLE ((uint32_t *)(ROM_APITABLE[9])) #define ROM_SYSTICKTABLE ((uint32_t *)(ROM_APITABLE[10])) #define ROM_TIMERTABLE ((uint32_t *)(ROM_APITABLE[11])) #define ROM_WATCHDOGTABLE ((uint32_t *)(ROM_APITABLE[12])) #define ROM_SYSCTLTABLE ((uint32_t *)(ROM_APITABLE[13])) #define ROM_INTERRUPTTABLE ((uint32_t *)(ROM_APITABLE[14])) #define ROM_USBTABLE ((uint32_t *)(ROM_APITABLE[16])) #define ROM_UDMATABLE ((uint32_t *)(ROM_APITABLE[17])) #define ROM_CANTABLE ((uint32_t *)(ROM_APITABLE[18])) #define ROM_HIBERNATETABLE ((uint32_t *)(ROM_APITABLE[19])) #define ROM_MPUTABLE ((uint32_t *)(ROM_APITABLE[20])) #define ROM_SOFTWARETABLE ((uint32_t *)(ROM_APITABLE[21])) #define ROM_EPITABLE ((uint32_t *)(ROM_APITABLE[23])) #define ROM_EEPROMTABLE ((uint32_t *)(ROM_APITABLE[24])) #define ROM_FPUTABLE ((uint32_t *)(ROM_APITABLE[26])) #define ROM_SMBUSTABLE ((uint32_t *)(ROM_APITABLE[29])) #define ROM_SYSEXCTABLE ((uint32_t *)(ROM_APITABLE[30])) #define ROM_ONEWIRETABLE ((uint32_t *)(ROM_APITABLE[34])) #define ROM_SPIFLASHTABLE ((uint32_t *)(ROM_APITABLE[38])) #define ROM_LCDTABLE ((uint32_t *)(ROM_APITABLE[41])) #define ROM_EMACTABLE ((uint32_t *)(ROM_APITABLE[42])) #define ROM_AESTABLE ((uint32_t *)(ROM_APITABLE[43])) #define ROM_CRCTABLE ((uint32_t *)(ROM_APITABLE[44])) #define ROM_DESTABLE ((uint32_t *)(ROM_APITABLE[45])) #define ROM_SHAMD5TABLE ((uint32_t *)(ROM_APITABLE[46])) //============================================================================* // // Macros for calling ROM functions in the ADC API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCSequenceDataGet \ ((int32_t (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum, \ uint32_t *pui32Buffer))ROM_ADCTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCIntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum))ROM_ADCTABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCIntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum))ROM_ADCTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCIntStatus \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum, \ bool bMasked))ROM_ADCTABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCIntClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum))ROM_ADCTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCSequenceEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum))ROM_ADCTABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCSequenceDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum))ROM_ADCTABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCSequenceConfigure \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum, \ uint32_t ui32Trigger, \ uint32_t ui32Priority))ROM_ADCTABLE[7]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCSequenceStepConfigure \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum, \ uint32_t ui32Step, \ uint32_t ui32Config))ROM_ADCTABLE[8]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCSequenceOverflow \ ((int32_t (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum))ROM_ADCTABLE[9]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCSequenceOverflowClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum))ROM_ADCTABLE[10]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCSequenceUnderflow \ ((int32_t (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum))ROM_ADCTABLE[11]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCSequenceUnderflowClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum))ROM_ADCTABLE[12]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCProcessorTrigger \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum))ROM_ADCTABLE[13]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCHardwareOversampleConfigure \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Factor))ROM_ADCTABLE[14]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCComparatorConfigure \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Comp, \ uint32_t ui32Config))ROM_ADCTABLE[15]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCComparatorRegionSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Comp, \ uint32_t ui32LowRef, \ uint32_t ui32HighRef))ROM_ADCTABLE[16]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCComparatorReset \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Comp, \ bool bTrigger, \ bool bInterrupt))ROM_ADCTABLE[17]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCComparatorIntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum))ROM_ADCTABLE[18]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCComparatorIntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum))ROM_ADCTABLE[19]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCComparatorIntStatus \ ((uint32_t (*)(uint32_t ui32Base))ROM_ADCTABLE[20]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCComparatorIntClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Status))ROM_ADCTABLE[21]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCReferenceSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Ref))ROM_ADCTABLE[22]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCReferenceGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_ADCTABLE[23]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCPhaseDelaySet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Phase))ROM_ADCTABLE[24]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCPhaseDelayGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_ADCTABLE[25]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCIntDisableEx \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_ADCTABLE[29]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCIntEnableEx \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_ADCTABLE[30]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCIntStatusEx \ ((uint32_t (*)(uint32_t ui32Base, \ bool bMasked))ROM_ADCTABLE[31]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCSequenceDMAEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum))ROM_ADCTABLE[32]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCSequenceDMADisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32SequenceNum))ROM_ADCTABLE[33]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ADCBusy \ ((bool (*)(uint32_t ui32Base))ROM_ADCTABLE[34]) #endif //============================================================================* // // Macros for calling ROM functions in the AES API. // //============================================================================* #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESIntStatus \ ((uint32_t (*)(uint32_t ui32Base, \ bool bMasked))ROM_AESTABLE[0]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESAuthLengthSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Length))ROM_AESTABLE[1]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config))ROM_AESTABLE[2]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESDataAuth \ ((bool (*)(uint32_t ui32Base, \ uint32_t *pui32Src, \ uint32_t ui32Length, \ uint32_t *pui32Tag))ROM_AESTABLE[3]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESDataProcess \ ((bool (*)(uint32_t ui32Base, \ uint32_t *pui32Src, \ uint32_t *pui32Dest, \ uint32_t ui32Length))ROM_AESTABLE[4]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESDataProcessAuth \ ((bool (*)(uint32_t ui32Base, \ uint32_t *pui32Src, \ uint32_t *pui32Dest, \ uint32_t ui32Length, \ uint32_t *pui32AuthSrc, \ uint32_t ui32AuthLength, \ uint32_t *pui32Tag))ROM_AESTABLE[5]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESDataRead \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32Dest))ROM_AESTABLE[6]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESDataReadNonBlocking \ ((bool (*)(uint32_t ui32Base, \ uint32_t *pui32Dest))ROM_AESTABLE[7]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESDataWrite \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32Src))ROM_AESTABLE[8]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESDataWriteNonBlocking \ ((bool (*)(uint32_t ui32Base, \ uint32_t *pui32Src))ROM_AESTABLE[9]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESDMADisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Flags))ROM_AESTABLE[10]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESDMAEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Flags))ROM_AESTABLE[11]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESIntClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_AESTABLE[12]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESIntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_AESTABLE[13]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESIntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_AESTABLE[14]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESIVSet \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32IVdata))ROM_AESTABLE[15]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESKey1Set \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32Key, \ uint32_t ui32Keysize))ROM_AESTABLE[16]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESKey2Set \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32Key, \ uint32_t ui32Keysize))ROM_AESTABLE[17]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESKey3Set \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32Key))ROM_AESTABLE[18]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESLengthSet \ ((void (*)(uint32_t ui32Base, \ uint64_t ui64Length))ROM_AESTABLE[19]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESReset \ ((void (*)(uint32_t ui32Base))ROM_AESTABLE[20]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESTagRead \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32TagData))ROM_AESTABLE[21]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_AESIVRead \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32IVdata))ROM_AESTABLE[22]) #endif //============================================================================* // // Macros for calling ROM functions in the CAN API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CANIntClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntClr))ROM_CANTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CANInit \ ((void (*)(uint32_t ui32Base))ROM_CANTABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CANEnable \ ((void (*)(uint32_t ui32Base))ROM_CANTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CANDisable \ ((void (*)(uint32_t ui32Base))ROM_CANTABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CANBitTimingSet \ ((void (*)(uint32_t ui32Base, \ tCANBitClkParms *psClkParms))ROM_CANTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CANBitTimingGet \ ((void (*)(uint32_t ui32Base, \ tCANBitClkParms *psClkParms))ROM_CANTABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CANMessageSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32ObjID, \ tCANMsgObject *psMsgObject, \ tMsgObjType eMsgType))ROM_CANTABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CANMessageGet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32ObjID, \ tCANMsgObject *psMsgObject, \ bool bClrPendingInt))ROM_CANTABLE[7]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CANStatusGet \ ((uint32_t (*)(uint32_t ui32Base, \ tCANStsReg eStatusReg))ROM_CANTABLE[8]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CANMessageClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32ObjID))ROM_CANTABLE[9]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CANIntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_CANTABLE[10]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CANIntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_CANTABLE[11]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CANIntStatus \ ((uint32_t (*)(uint32_t ui32Base, \ tCANIntStsReg eIntStsReg))ROM_CANTABLE[12]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CANRetryGet \ ((bool (*)(uint32_t ui32Base))ROM_CANTABLE[13]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CANRetrySet \ ((void (*)(uint32_t ui32Base, \ bool bAutoRetry))ROM_CANTABLE[14]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CANErrCntrGet \ ((bool (*)(uint32_t ui32Base, \ uint32_t *pui32RxCount, \ uint32_t *pui32TxCount))ROM_CANTABLE[15]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CANBitRateSet \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32SourceClock, \ uint32_t ui32BitRate))ROM_CANTABLE[16]) #endif //============================================================================* // // Macros for calling ROM functions in the Comparator API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ComparatorIntClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Comp))ROM_COMPARATORTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ComparatorConfigure \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Comp, \ uint32_t ui32Config))ROM_COMPARATORTABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ComparatorRefSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Ref))ROM_COMPARATORTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ComparatorValueGet \ ((bool (*)(uint32_t ui32Base, \ uint32_t ui32Comp))ROM_COMPARATORTABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ComparatorIntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Comp))ROM_COMPARATORTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ComparatorIntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Comp))ROM_COMPARATORTABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_ComparatorIntStatus \ ((bool (*)(uint32_t ui32Base, \ uint32_t ui32Comp, \ bool bMasked))ROM_COMPARATORTABLE[6]) #endif //============================================================================* // // Macros for calling ROM functions in the CRC API. // //============================================================================* #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CRCConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32CRCConfig))ROM_CRCTABLE[0]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CRCDataProcess \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t *pui32DataIn, \ uint32_t ui32DataLength, \ bool bPPResult))ROM_CRCTABLE[1]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CRCDataWrite \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Data))ROM_CRCTABLE[2]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CRCResultRead \ ((uint32_t (*)(uint32_t ui32Base, \ bool bPPResult))ROM_CRCTABLE[3]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_CRCSeedSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Seed))ROM_CRCTABLE[4]) #endif //============================================================================* // // Macros for calling ROM functions in the DES API. // //============================================================================* #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_DESIntStatus \ ((uint32_t (*)(uint32_t ui32Base, \ bool bMasked))ROM_DESTABLE[0]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_DESConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config))ROM_DESTABLE[1]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_DESDataRead \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32Dest))ROM_DESTABLE[2]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_DESDataReadNonBlocking \ ((bool (*)(uint32_t ui32Base, \ uint32_t *pui32Dest))ROM_DESTABLE[3]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_DESDataProcess \ ((bool (*)(uint32_t ui32Base, \ uint32_t *pui32Src, \ uint32_t *pui32Dest, \ uint32_t ui32Length))ROM_DESTABLE[4]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_DESDataWrite \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32Src))ROM_DESTABLE[5]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_DESDataWriteNonBlocking \ ((bool (*)(uint32_t ui32Base, \ uint32_t *pui32Src))ROM_DESTABLE[6]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_DESDMADisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Flags))ROM_DESTABLE[7]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_DESDMAEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Flags))ROM_DESTABLE[8]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_DESIntClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_DESTABLE[9]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_DESIntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_DESTABLE[10]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_DESIntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_DESTABLE[11]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_DESIVSet \ ((bool (*)(uint32_t ui32Base, \ uint32_t *pui32IVdata))ROM_DESTABLE[12]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_DESKeySet \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32Key))ROM_DESTABLE[13]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_DESLengthSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Length))ROM_DESTABLE[14]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_DESReset \ ((void (*)(uint32_t ui32Base))ROM_DESTABLE[15]) #endif //============================================================================* // // Macros for calling ROM functions in the EEPROM API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EEPROMRead \ ((void (*)(uint32_t *pui32Data, \ uint32_t ui32Address, \ uint32_t ui32Count))ROM_EEPROMTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EEPROMBlockCountGet \ ((uint32_t (*)(void))ROM_EEPROMTABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EEPROMBlockHide \ ((void (*)(uint32_t ui32Block))ROM_EEPROMTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EEPROMBlockLock \ ((uint32_t (*)(uint32_t ui32Block))ROM_EEPROMTABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EEPROMBlockPasswordSet \ ((uint32_t (*)(uint32_t ui32Block, \ uint32_t *pui32Password, \ uint32_t ui32Count))ROM_EEPROMTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EEPROMBlockProtectGet \ ((uint32_t (*)(uint32_t ui32Block))ROM_EEPROMTABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EEPROMBlockProtectSet \ ((uint32_t (*)(uint32_t ui32Block, \ uint32_t ui32Protect))ROM_EEPROMTABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EEPROMBlockUnlock \ ((uint32_t (*)(uint32_t ui32Block, \ uint32_t *pui32Password, \ uint32_t ui32Count))ROM_EEPROMTABLE[7]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EEPROMIntClear \ ((void (*)(uint32_t ui32IntFlags))ROM_EEPROMTABLE[8]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EEPROMIntDisable \ ((void (*)(uint32_t ui32IntFlags))ROM_EEPROMTABLE[9]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EEPROMIntEnable \ ((void (*)(uint32_t ui32IntFlags))ROM_EEPROMTABLE[10]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EEPROMIntStatus \ ((uint32_t (*)(bool bMasked))ROM_EEPROMTABLE[11]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) #define ROM_EEPROMMassErase \ ((uint32_t (*)(void))ROM_EEPROMTABLE[12]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EEPROMProgram \ ((uint32_t (*)(uint32_t *pui32Data, \ uint32_t ui32Address, \ uint32_t ui32Count))ROM_EEPROMTABLE[13]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EEPROMProgramNonBlocking \ ((uint32_t (*)(uint32_t ui32Data, \ uint32_t ui32Address))ROM_EEPROMTABLE[14]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EEPROMSizeGet \ ((uint32_t (*)(void))ROM_EEPROMTABLE[15]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EEPROMStatusGet \ ((uint32_t (*)(void))ROM_EEPROMTABLE[16]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EEPROMInit \ ((uint32_t (*)(void))ROM_EEPROMTABLE[17]) #endif //============================================================================* // // Macros for calling ROM functions in the EPI API. // //============================================================================* #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIIntStatus \ ((uint32_t (*)(uint32_t ui32Base, \ bool bMasked))ROM_EPITABLE[0]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIModeSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Mode))ROM_EPITABLE[1]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIDividerSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Divider))ROM_EPITABLE[2]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIConfigSDRAMSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config, \ uint32_t ui32Refresh))ROM_EPITABLE[3]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIConfigGPModeSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config, \ uint32_t ui32FrameCount, \ uint32_t ui32MaxWait))ROM_EPITABLE[4]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIConfigHB8Set \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config, \ uint32_t ui32MaxWait))ROM_EPITABLE[5]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIConfigHB16Set \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config, \ uint32_t ui32MaxWait))ROM_EPITABLE[6]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIAddressMapSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Map))ROM_EPITABLE[7]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPINonBlockingReadConfigure \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Channel, \ uint32_t ui32DataSize, \ uint32_t ui32Address))ROM_EPITABLE[8]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPINonBlockingReadStart \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Channel, \ uint32_t ui32Count))ROM_EPITABLE[9]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPINonBlockingReadStop \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Channel))ROM_EPITABLE[10]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPINonBlockingReadCount \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Channel))ROM_EPITABLE[11]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPINonBlockingReadAvail \ ((uint32_t (*)(uint32_t ui32Base))ROM_EPITABLE[12]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPINonBlockingReadGet32 \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Count, \ uint32_t *pui32Buf))ROM_EPITABLE[13]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPINonBlockingReadGet16 \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Count, \ uint16_t *pui16Buf))ROM_EPITABLE[14]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPINonBlockingReadGet8 \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Count, \ uint8_t *pui8Buf))ROM_EPITABLE[15]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIFIFOConfig \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config))ROM_EPITABLE[16]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIWriteFIFOCountGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_EPITABLE[17]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIIntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_EPITABLE[18]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIIntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_EPITABLE[19]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIIntErrorStatus \ ((uint32_t (*)(uint32_t ui32Base))ROM_EPITABLE[20]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIIntErrorClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32ErrFlags))ROM_EPITABLE[21]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIDividerCSSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32CS, \ uint32_t ui32Divider))ROM_EPITABLE[22]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIDMATxCount \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Count))ROM_EPITABLE[23]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIConfigHB8CSSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32CS, \ uint32_t ui32Config))ROM_EPITABLE[24]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIConfigHB16CSSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32CS, \ uint32_t ui32Config))ROM_EPITABLE[25]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIConfigHB8TimingSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32CS, \ uint32_t ui32Config))ROM_EPITABLE[26]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIConfigHB16TimingSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32CS, \ uint32_t ui32Config))ROM_EPITABLE[27]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIPSRAMConfigRegSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32CS, \ uint32_t ui32CR))ROM_EPITABLE[28]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIPSRAMConfigRegRead \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32CS))ROM_EPITABLE[29]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIPSRAMConfigRegGetNonBlocking \ ((bool (*)(uint32_t ui32Base, \ uint32_t ui32CS, \ uint32_t *pui32CR))ROM_EPITABLE[30]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EPIPSRAMConfigRegGet \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32CS))ROM_EPITABLE[31]) #endif //============================================================================* // // Macros for calling ROM functions in the EMAC API. // //============================================================================* #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACIntStatus \ ((uint32_t (*)(uint32_t ui32Base, \ bool bMasked))ROM_EMACTABLE[0]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACAddrGet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Index, \ uint8_t *pui8MACAddr))ROM_EMACTABLE[1]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACAddrSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Index, \ const uint8_t *pui8MACAddr))ROM_EMACTABLE[2]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACConfigGet \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32Config, \ uint32_t *pui32Mode, \ uint32_t *pui32RxMaxFrameSize))ROM_EMACTABLE[3]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config, \ uint32_t ui32ModeFlags, \ uint32_t ui32RxMaxFrameSize))ROM_EMACTABLE[4]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACDMAStateGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_EMACTABLE[5]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACFrameFilterGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_EMACTABLE[6]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACFrameFilterSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32FilterOpts))ROM_EMACTABLE[7]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACInit \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32SysClk, \ uint32_t ui32BusConfig, \ uint32_t ui32RxBurst, \ uint32_t ui32TxBurst, \ uint32_t ui32DescSkipSize))ROM_EMACTABLE[8]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACIntClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_EMACTABLE[9]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACIntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_EMACTABLE[10]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACIntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_EMACTABLE[11]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACPHYConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config))ROM_EMACTABLE[12]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACPHYPowerOff \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8PhyAddr))ROM_EMACTABLE[13]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACPHYPowerOn \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8PhyAddr))ROM_EMACTABLE[14]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACPHYRead \ ((uint16_t (*)(uint32_t ui32Base, \ uint8_t ui8PhyAddr, \ uint8_t ui8RegAddr))ROM_EMACTABLE[15]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACPHYWrite \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8PhyAddr, \ uint8_t ui8RegAddr, \ uint16_t ui16Data))ROM_EMACTABLE[16]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACReset \ ((void (*)(uint32_t ui32Base))ROM_EMACTABLE[17]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACRxDisable \ ((void (*)(uint32_t ui32Base))ROM_EMACTABLE[18]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACRxDMACurrentBufferGet \ ((uint8_t * (*)(uint32_t ui32Base))ROM_EMACTABLE[19]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACRxDMACurrentDescriptorGet \ ((tEMACDMADescriptor * (*)(uint32_t ui32Base))ROM_EMACTABLE[20]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACRxDMADescriptorListGet \ ((tEMACDMADescriptor * (*)(uint32_t ui32Base))ROM_EMACTABLE[21]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACRxDMADescriptorListSet \ ((void (*)(uint32_t ui32Base, \ tEMACDMADescriptor *pDescriptor))ROM_EMACTABLE[22]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACRxDMAPollDemand \ ((void (*)(uint32_t ui32Base))ROM_EMACTABLE[23]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACRxEnable \ ((void (*)(uint32_t ui32Base))ROM_EMACTABLE[24]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACRxWatchdogTimerSet \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8Timeout))ROM_EMACTABLE[25]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACStatusGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_EMACTABLE[26]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTxDisable \ ((void (*)(uint32_t ui32Base))ROM_EMACTABLE[27]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTxDMACurrentBufferGet \ ((uint8_t * (*)(uint32_t ui32Base))ROM_EMACTABLE[28]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTxDMACurrentDescriptorGet \ ((tEMACDMADescriptor * (*)(uint32_t ui32Base))ROM_EMACTABLE[29]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTxDMADescriptorListGet \ ((tEMACDMADescriptor * (*)(uint32_t ui32Base))ROM_EMACTABLE[30]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTxDMADescriptorListSet \ ((void (*)(uint32_t ui32Base, \ tEMACDMADescriptor *pDescriptor))ROM_EMACTABLE[31]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTxDMAPollDemand \ ((void (*)(uint32_t ui32Base))ROM_EMACTABLE[32]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTxEnable \ ((void (*)(uint32_t ui32Base))ROM_EMACTABLE[33]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTxFlush \ ((void (*)(uint32_t ui32Base))ROM_EMACTABLE[34]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACAddrFilterGet \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Index))ROM_EMACTABLE[35]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACAddrFilterSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Index, \ uint32_t ui32Config))ROM_EMACTABLE[36]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACHashFilterBitCalculate \ ((uint32_t (*)(uint8_t *pui8MACAddr))ROM_EMACTABLE[37]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACHashFilterGet \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32HashHi, \ uint32_t *pui32HashLo))ROM_EMACTABLE[38]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACHashFilterSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32HashHi, \ uint32_t ui32HashLo))ROM_EMACTABLE[39]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACNumAddrGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_EMACTABLE[40]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACPHYExtendedRead \ ((uint16_t (*)(uint32_t ui32Base, \ uint8_t ui8PhyAddr, \ uint16_t ui16RegAddr))ROM_EMACTABLE[41]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACPHYExtendedWrite \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8PhyAddr, \ uint16_t ui16RegAddr, \ uint16_t ui16Data))ROM_EMACTABLE[42]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACPowerManagementControlGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_EMACTABLE[43]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACPowerManagementControlSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Flags))ROM_EMACTABLE[44]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACPowerManagementStatusGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_EMACTABLE[45]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACRemoteWakeUpFrameFilterGet \ ((void (*)(uint32_t ui32Base, \ tEMACWakeUpFrameFilter *pFilter))ROM_EMACTABLE[46]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACRemoteWakeUpFrameFilterSet \ ((void (*)(uint32_t ui32Base, \ const tEMACWakeUpFrameFilter *pFilter))ROM_EMACTABLE[47]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTimestampAddendSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Seconds))ROM_EMACTABLE[48]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTimestampConfigGet \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t *pui32SubSecondInc))ROM_EMACTABLE[49]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTimestampConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config, \ uint32_t ui32SubSecondInc))ROM_EMACTABLE[50]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTimestampDisable \ ((void (*)(uint32_t ui32Base))ROM_EMACTABLE[51]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTimestampEnable \ ((void (*)(uint32_t ui32Base))ROM_EMACTABLE[52]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTimestampIntStatus \ ((uint32_t (*)(uint32_t ui32Base))ROM_EMACTABLE[53]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTimestampPPSCommand \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8Cmd))ROM_EMACTABLE[54]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTimestampPPSCommandModeSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config))ROM_EMACTABLE[55]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTimestampPPSPeriodSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Period, \ uint32_t ui32Width))ROM_EMACTABLE[56]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTimestampPPSSimpleModeSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32FreqConfig))ROM_EMACTABLE[57]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTimestampSysTimeGet \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32Seconds, \ uint32_t *pui32SubSeconds))ROM_EMACTABLE[58]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTimestampSysTimeSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Seconds, \ uint32_t ui32SubSeconds))ROM_EMACTABLE[59]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTimestampSysTimeUpdate \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Seconds, \ uint32_t ui32SubSeconds, \ bool bInc))ROM_EMACTABLE[60]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTimestampTargetIntDisable \ ((void (*)(uint32_t ui32Base))ROM_EMACTABLE[61]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTimestampTargetIntEnable \ ((void (*)(uint32_t ui32Base))ROM_EMACTABLE[62]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACTimestampTargetSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Seconds, \ uint32_t ui32Nanoseconds))ROM_EMACTABLE[63]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACVLANHashFilterBitCalculate \ ((uint32_t (*)(uint16_t ui16Tag))ROM_EMACTABLE[64]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACVLANHashFilterGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_EMACTABLE[65]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACVLANHashFilterSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Hash))ROM_EMACTABLE[66]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACVLANRxConfigGet \ ((uint32_t (*)(uint32_t ui32Base, \ uint16_t *pui16Tag))ROM_EMACTABLE[67]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACVLANRxConfigSet \ ((void (*)(uint32_t ui32Base, \ uint16_t ui16Tag, \ uint32_t ui32Config))ROM_EMACTABLE[68]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACVLANTxConfigGet \ ((uint32_t (*)(uint32_t ui32Base, \ uint16_t *pui16Tag))ROM_EMACTABLE[69]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_EMACVLANTxConfigSet \ ((void (*)(uint32_t ui32Base, \ uint16_t ui16Tag, \ uint32_t ui32Config))ROM_EMACTABLE[70]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UpdateEMAC \ ((void (*)(uint32_t ui32Clock))ROM_EMACTABLE[71]) #endif //============================================================================* // // Macros for calling ROM functions in the Flash API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FlashProgram \ ((int32_t (*)(uint32_t *pui32Data, \ uint32_t ui32Address, \ uint32_t ui32Count))ROM_FLASHTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FlashErase \ ((int32_t (*)(uint32_t ui32Address))ROM_FLASHTABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FlashProtectGet \ ((tFlashProtection (*)(uint32_t ui32Address))ROM_FLASHTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FlashProtectSet \ ((int32_t (*)(uint32_t ui32Address, \ tFlashProtection eProtect))ROM_FLASHTABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FlashProtectSave \ ((int32_t (*)(void))ROM_FLASHTABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FlashUserGet \ ((int32_t (*)(uint32_t *pui32User0, \ uint32_t *pui32User1))ROM_FLASHTABLE[7]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FlashUserSet \ ((int32_t (*)(uint32_t ui32User0, \ uint32_t ui32User1))ROM_FLASHTABLE[8]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FlashUserSave \ ((int32_t (*)(void))ROM_FLASHTABLE[9]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FlashIntEnable \ ((void (*)(uint32_t ui32IntFlags))ROM_FLASHTABLE[10]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FlashIntDisable \ ((void (*)(uint32_t ui32IntFlags))ROM_FLASHTABLE[11]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FlashIntStatus \ ((uint32_t (*)(bool bMasked))ROM_FLASHTABLE[12]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FlashIntClear \ ((void (*)(uint32_t ui32IntFlags))ROM_FLASHTABLE[13]) #endif //============================================================================* // // Macros for calling ROM functions in the FPU API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FPUEnable \ ((void (*)(void))ROM_FPUTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FPUDisable \ ((void (*)(void))ROM_FPUTABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FPUFlushToZeroModeSet \ ((void (*)(uint32_t ui32Mode))ROM_FPUTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FPUHalfPrecisionModeSet \ ((void (*)(uint32_t ui32Mode))ROM_FPUTABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FPULazyStackingEnable \ ((void (*)(void))ROM_FPUTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FPUNaNModeSet \ ((void (*)(uint32_t ui32Mode))ROM_FPUTABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FPURoundingModeSet \ ((void (*)(uint32_t ui32Mode))ROM_FPUTABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FPUStackingDisable \ ((void (*)(void))ROM_FPUTABLE[7]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_FPUStackingEnable \ ((void (*)(void))ROM_FPUTABLE[8]) #endif //============================================================================* // // Macros for calling ROM functions in the GPIO API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinWrite \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins, \ uint8_t ui8Val))ROM_GPIOTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIODirModeSet \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins, \ uint32_t ui32PinIO))ROM_GPIOTABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIODirModeGet \ ((uint32_t (*)(uint32_t ui32Port, \ uint8_t ui8Pin))ROM_GPIOTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOIntTypeSet \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins, \ uint32_t ui32IntType))ROM_GPIOTABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOIntTypeGet \ ((uint32_t (*)(uint32_t ui32Port, \ uint8_t ui8Pin))ROM_GPIOTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) #define ROM_GPIOPadConfigSet \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins, \ uint32_t ui32Strength, \ uint32_t ui32PadType))ROM_GPIOTABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPadConfigGet \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pin, \ uint32_t *pui32Strength, \ uint32_t *pui32PadType))ROM_GPIOTABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinRead \ ((int32_t (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[11]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) #define ROM_GPIOPinTypeCAN \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[12]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinTypeComparator \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[13]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinTypeGPIOInput \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[14]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinTypeGPIOOutput \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[15]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinTypeI2C \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[16]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinTypePWM \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[17]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinTypeQEI \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[18]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinTypeSSI \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[19]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinTypeTimer \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[20]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinTypeUART \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[21]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinTypeGPIOOutputOD \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[22]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinTypeADC \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[23]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinTypeUSBDigital \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[24]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinConfigure \ ((void (*)(uint32_t ui32PinConfig))ROM_GPIOTABLE[26]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinTypeUSBAnalog \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[28]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIODMATriggerEnable \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[31]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIODMATriggerDisable \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[32]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOADCTriggerEnable \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[33]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOADCTriggerDisable \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[34]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinTypeI2CSCL \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[39]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinTypeOneWire \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[44]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinTypeWakeHigh \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[48]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinTypeWakeLow \ ((void (*)(uint32_t ui32Port, \ uint8_t ui8Pins))ROM_GPIOTABLE[49]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOIntClear \ ((void (*)(uint32_t ui32Port, \ uint32_t ui32IntFlags))ROM_GPIOTABLE[51]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOIntDisable \ ((void (*)(uint32_t ui32Port, \ uint32_t ui32IntFlags))ROM_GPIOTABLE[52]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOIntEnable \ ((void (*)(uint32_t ui32Port, \ uint32_t ui32IntFlags))ROM_GPIOTABLE[53]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOIntStatus \ ((uint32_t (*)(uint32_t ui32Port, \ bool bMasked))ROM_GPIOTABLE[54]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_GPIOPinWakeStatus \ ((uint32_t (*)(uint32_t ui32Port))ROM_GPIOTABLE[55]) #endif //============================================================================* // // Macros for calling ROM functions in the Hibernate API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateIntClear \ ((void (*)(uint32_t ui32IntFlags))ROM_HIBERNATETABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateEnableExpClk \ ((void (*)(uint32_t ui32HibClk))ROM_HIBERNATETABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateDisable \ ((void (*)(void))ROM_HIBERNATETABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateRTCEnable \ ((void (*)(void))ROM_HIBERNATETABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateRTCDisable \ ((void (*)(void))ROM_HIBERNATETABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateWakeSet \ ((void (*)(uint32_t ui32WakeFlags))ROM_HIBERNATETABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateWakeGet \ ((uint32_t (*)(void))ROM_HIBERNATETABLE[7]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateLowBatSet \ ((void (*)(uint32_t ui32LowBatFlags))ROM_HIBERNATETABLE[8]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateLowBatGet \ ((uint32_t (*)(void))ROM_HIBERNATETABLE[9]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateRTCSet \ ((void (*)(uint32_t ui32RTCValue))ROM_HIBERNATETABLE[10]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateRTCGet \ ((uint32_t (*)(void))ROM_HIBERNATETABLE[11]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateRTCTrimSet \ ((void (*)(uint32_t ui32Trim))ROM_HIBERNATETABLE[16]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateRTCTrimGet \ ((uint32_t (*)(void))ROM_HIBERNATETABLE[17]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateDataSet \ ((void (*)(uint32_t *pui32Data, \ uint32_t ui32Count))ROM_HIBERNATETABLE[18]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateDataGet \ ((void (*)(uint32_t *pui32Data, \ uint32_t ui32Count))ROM_HIBERNATETABLE[19]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateRequest \ ((void (*)(void))ROM_HIBERNATETABLE[20]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateIntEnable \ ((void (*)(uint32_t ui32IntFlags))ROM_HIBERNATETABLE[21]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateIntDisable \ ((void (*)(uint32_t ui32IntFlags))ROM_HIBERNATETABLE[22]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateIntStatus \ ((uint32_t (*)(bool bMasked))ROM_HIBERNATETABLE[23]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateIsActive \ ((uint32_t (*)(void))ROM_HIBERNATETABLE[24]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateRTCSSGet \ ((uint32_t (*)(void))ROM_HIBERNATETABLE[27]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateClockConfig \ ((void (*)(uint32_t ui32Config))ROM_HIBERNATETABLE[28]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateBatCheckStart \ ((void (*)(void))ROM_HIBERNATETABLE[29]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateBatCheckDone \ ((uint32_t (*)(void))ROM_HIBERNATETABLE[30]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateGPIORetentionEnable \ ((void (*)(void))ROM_HIBERNATETABLE[31]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateGPIORetentionDisable \ ((void (*)(void))ROM_HIBERNATETABLE[32]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateGPIORetentionGet \ ((bool (*)(void))ROM_HIBERNATETABLE[33]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateCounterMode \ ((void (*)(uint32_t ui32Config))ROM_HIBERNATETABLE[34]) #endif #if defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateCalendarSet \ ((void (*)(struct tm *psTime))ROM_HIBERNATETABLE[35]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateCalendarGet \ ((int (*)(struct tm *psTime))ROM_HIBERNATETABLE[36]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateCalendarMatchSet \ ((void (*)(uint32_t ui32Index, \ struct tm *psTime))ROM_HIBERNATETABLE[37]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateCalendarMatchGet \ ((void (*)(uint32_t ui32Index, \ struct tm *psTime))ROM_HIBERNATETABLE[38]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateTamperDisable \ ((void (*)(void))ROM_HIBERNATETABLE[39]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateTamperEnable \ ((void (*)(void))ROM_HIBERNATETABLE[40]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateTamperEventsClear \ ((void (*)(void))ROM_HIBERNATETABLE[41]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateTamperEventsConfig \ ((void (*)(uint32_t ui32Config))ROM_HIBERNATETABLE[42]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateTamperEventsGet \ ((bool (*)(uint32_t ui32Index, \ uint32_t *pui32RTC, \ uint32_t *pui32Event))ROM_HIBERNATETABLE[43]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateTamperExtOscValid \ ((bool (*)(void))ROM_HIBERNATETABLE[44]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateTamperExtOscRecover \ ((void (*)(void))ROM_HIBERNATETABLE[45]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateTamperIODisable \ ((void (*)(uint32_t ui32Input))ROM_HIBERNATETABLE[46]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateTamperIOEnable \ ((void (*)(uint32_t ui32Input, \ uint32_t ui32Config))ROM_HIBERNATETABLE[47]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateTamperStatusGet \ ((uint32_t (*)(void))ROM_HIBERNATETABLE[48]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateRTCMatchGet \ ((uint32_t (*)(uint32_t ui32Match))ROM_HIBERNATETABLE[49]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateRTCMatchSet \ ((void (*)(uint32_t ui32Match, \ uint32_t ui32Value))ROM_HIBERNATETABLE[50]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateRTCSSMatchGet \ ((uint32_t (*)(uint32_t ui32Match))ROM_HIBERNATETABLE[51]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_HibernateRTCSSMatchSet \ ((void (*)(uint32_t ui32Match, \ uint32_t ui32Value))ROM_HIBERNATETABLE[52]) #endif //============================================================================* // // Macros for calling ROM functions in the I2C API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterDataPut \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8Data))ROM_I2CTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterInitExpClk \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32I2CClk, \ bool bFast))ROM_I2CTABLE[1]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveInit \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8SlaveAddr))ROM_I2CTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterEnable \ ((void (*)(uint32_t ui32Base))ROM_I2CTABLE[3]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveEnable \ ((void (*)(uint32_t ui32Base))ROM_I2CTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterDisable \ ((void (*)(uint32_t ui32Base))ROM_I2CTABLE[5]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveDisable \ ((void (*)(uint32_t ui32Base))ROM_I2CTABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterIntEnable \ ((void (*)(uint32_t ui32Base))ROM_I2CTABLE[7]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveIntEnable \ ((void (*)(uint32_t ui32Base))ROM_I2CTABLE[8]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterIntDisable \ ((void (*)(uint32_t ui32Base))ROM_I2CTABLE[9]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveIntDisable \ ((void (*)(uint32_t ui32Base))ROM_I2CTABLE[10]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterIntStatus \ ((bool (*)(uint32_t ui32Base, \ bool bMasked))ROM_I2CTABLE[11]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveIntStatus \ ((bool (*)(uint32_t ui32Base, \ bool bMasked))ROM_I2CTABLE[12]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterIntClear \ ((void (*)(uint32_t ui32Base))ROM_I2CTABLE[13]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveIntClear \ ((void (*)(uint32_t ui32Base))ROM_I2CTABLE[14]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterSlaveAddrSet \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8SlaveAddr, \ bool bReceive))ROM_I2CTABLE[15]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterBusy \ ((bool (*)(uint32_t ui32Base))ROM_I2CTABLE[16]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterBusBusy \ ((bool (*)(uint32_t ui32Base))ROM_I2CTABLE[17]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterControl \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Cmd))ROM_I2CTABLE[18]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterErr \ ((uint32_t (*)(uint32_t ui32Base))ROM_I2CTABLE[19]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterDataGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_I2CTABLE[20]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveStatus \ ((uint32_t (*)(uint32_t ui32Base))ROM_I2CTABLE[21]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveDataPut \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8Data))ROM_I2CTABLE[22]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveDataGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_I2CTABLE[23]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UpdateI2C \ ((void (*)(void))ROM_I2CTABLE[24]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveIntEnableEx \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_I2CTABLE[25]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveIntDisableEx \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_I2CTABLE[26]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveIntStatusEx \ ((uint32_t (*)(uint32_t ui32Base, \ bool bMasked))ROM_I2CTABLE[27]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveIntClearEx \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_I2CTABLE[28]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterIntEnableEx \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_I2CTABLE[29]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterIntDisableEx \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_I2CTABLE[30]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterIntStatusEx \ ((uint32_t (*)(uint32_t ui32Base, \ bool bMasked))ROM_I2CTABLE[31]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterIntClearEx \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_I2CTABLE[32]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterTimeoutSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Value))ROM_I2CTABLE[33]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveACKOverride \ ((void (*)(uint32_t ui32Base, \ bool bEnable))ROM_I2CTABLE[34]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveACKValueSet \ ((void (*)(uint32_t ui32Base, \ bool bACK))ROM_I2CTABLE[35]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveAddressSet \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8AddrNum, \ uint8_t ui8SlaveAddr))ROM_I2CTABLE[37]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterLineStateGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_I2CTABLE[38]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CTxFIFOConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config))ROM_I2CTABLE[39]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CTxFIFOFlush \ ((void (*)(uint32_t ui32Base))ROM_I2CTABLE[40]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CRxFIFOConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config))ROM_I2CTABLE[41]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CRxFIFOFlush \ ((void (*)(uint32_t ui32Base))ROM_I2CTABLE[42]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CFIFOStatus \ ((uint32_t (*)(uint32_t ui32Base))ROM_I2CTABLE[43]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CFIFODataPut \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8Data))ROM_I2CTABLE[44]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CFIFODataPutNonBlocking \ ((uint32_t (*)(uint32_t ui32Base, \ uint8_t ui8Data))ROM_I2CTABLE[45]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CFIFODataGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_I2CTABLE[46]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CFIFODataGetNonBlocking \ ((uint32_t (*)(uint32_t ui32Base, \ uint8_t *pui8Data))ROM_I2CTABLE[47]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterBurstLengthSet \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8Length))ROM_I2CTABLE[48]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterBurstCountGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_I2CTABLE[49]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveFIFODisable \ ((void (*)(uint32_t ui32Base))ROM_I2CTABLE[50]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CSlaveFIFOEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config))ROM_I2CTABLE[51]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_I2CMasterGlitchFilterConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config))ROM_I2CTABLE[54]) #endif //============================================================================* // // Macros for calling ROM functions in the Interrupt API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_IntEnable \ ((void (*)(uint32_t ui32Interrupt))ROM_INTERRUPTTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_IntMasterEnable \ ((bool (*)(void))ROM_INTERRUPTTABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_IntMasterDisable \ ((bool (*)(void))ROM_INTERRUPTTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_IntDisable \ ((void (*)(uint32_t ui32Interrupt))ROM_INTERRUPTTABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_IntPriorityGroupingSet \ ((void (*)(uint32_t ui32Bits))ROM_INTERRUPTTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_IntPriorityGroupingGet \ ((uint32_t (*)(void))ROM_INTERRUPTTABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_IntPrioritySet \ ((void (*)(uint32_t ui32Interrupt, \ uint8_t ui8Priority))ROM_INTERRUPTTABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_IntPriorityGet \ ((int32_t (*)(uint32_t ui32Interrupt))ROM_INTERRUPTTABLE[7]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_IntPendSet \ ((void (*)(uint32_t ui32Interrupt))ROM_INTERRUPTTABLE[8]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_IntPendClear \ ((void (*)(uint32_t ui32Interrupt))ROM_INTERRUPTTABLE[9]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_IntPriorityMaskSet \ ((void (*)(uint32_t ui32PriorityMask))ROM_INTERRUPTTABLE[10]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_IntPriorityMaskGet \ ((uint32_t (*)(void))ROM_INTERRUPTTABLE[11]) #endif #if defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_IntIsEnabled \ ((uint32_t (*)(uint32_t ui32Interrupt))ROM_INTERRUPTTABLE[12]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_IntTrigger \ ((void (*)(uint32_t ui32Interrupt))ROM_INTERRUPTTABLE[13]) #endif //============================================================================* // // Macros for calling ROM functions in the LCD API. // //============================================================================* #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDIntStatus \ ((uint32_t (*)(uint32_t ui32Base, \ bool bMasked))ROM_LCDTABLE[0]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDClockReset \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Clocks))ROM_LCDTABLE[1]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDDMAConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config))ROM_LCDTABLE[2]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDIDDCommandWrite \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32CS, \ uint16_t ui16Cmd))ROM_LCDTABLE[3]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDIDDConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config))ROM_LCDTABLE[4]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDIDDDataRead \ ((uint16_t (*)(uint32_t ui32Base, \ uint32_t ui32CS))ROM_LCDTABLE[5]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDIDDDataWrite \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32CS, \ uint16_t ui16Data))ROM_LCDTABLE[6]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDIDDDMADisable \ ((void (*)(uint32_t ui32Base))ROM_LCDTABLE[7]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDIDDDMAWrite \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32CS, \ const uint32_t *pui32Data, \ uint32_t ui32Count))ROM_LCDTABLE[8]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDIDDIndexedRead \ ((uint16_t (*)(uint32_t ui32Base, \ uint32_t ui32CS, \ uint16_t ui16Addr))ROM_LCDTABLE[9]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDIDDIndexedWrite \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32CS, \ uint16_t ui16Addr, \ uint16_t ui16Data))ROM_LCDTABLE[10]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDIDDStatusRead \ ((uint16_t (*)(uint32_t ui32Base, \ uint32_t ui32CS))ROM_LCDTABLE[11]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDIDDTimingSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32CS, \ const tLCDIDDTiming *pTiming))ROM_LCDTABLE[12]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDIntClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_LCDTABLE[13]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDIntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_LCDTABLE[14]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDIntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_LCDTABLE[15]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDModeSet \ ((uint32_t (*)(uint32_t ui32Base, \ uint8_t ui8Mode, \ uint32_t ui32PixClk, \ uint32_t ui32SysClk))ROM_LCDTABLE[16]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDRasterACBiasIntCountSet \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8Count))ROM_LCDTABLE[17]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDRasterConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config, \ uint8_t ui8PalLoadDelay))ROM_LCDTABLE[18]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDRasterDisable \ ((void (*)(uint32_t ui32Base))ROM_LCDTABLE[19]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDRasterEnable \ ((void (*)(uint32_t ui32Base))ROM_LCDTABLE[20]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDRasterFrameBufferSet \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8Buffer, \ uint32_t *pui32Addr, \ uint32_t ui32NumBytes))ROM_LCDTABLE[21]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDRasterPaletteSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Type, \ uint32_t *pui32PalAddr, \ const uint32_t *pui32SrcColors, \ uint32_t ui32Start, \ uint32_t ui32Count))ROM_LCDTABLE[22]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDRasterSubPanelConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Flags, \ uint32_t ui32BottomLines, \ uint32_t ui32DefaultPixel))ROM_LCDTABLE[23]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDRasterSubPanelDisable \ ((void (*)(uint32_t ui32Base))ROM_LCDTABLE[24]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDRasterSubPanelEnable \ ((void (*)(uint32_t ui32Base))ROM_LCDTABLE[25]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDRasterTimingSet \ ((void (*)(uint32_t ui32Base, \ const tLCDRasterTiming *pTiming))ROM_LCDTABLE[26]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_LCDRasterEnabled \ ((bool (*)(uint32_t ui32Base))ROM_LCDTABLE[27]) #endif //============================================================================* // // Macros for calling ROM functions in the MPU API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_MPUEnable \ ((void (*)(uint32_t ui32MPUConfig))ROM_MPUTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_MPUDisable \ ((void (*)(void))ROM_MPUTABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_MPURegionCountGet \ ((uint32_t (*)(void))ROM_MPUTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_MPURegionEnable \ ((void (*)(uint32_t ui32Region))ROM_MPUTABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_MPURegionDisable \ ((void (*)(uint32_t ui32Region))ROM_MPUTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_MPURegionSet \ ((void (*)(uint32_t ui32Region, \ uint32_t ui32Addr, \ uint32_t ui32Flags))ROM_MPUTABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_MPURegionGet \ ((void (*)(uint32_t ui32Region, \ uint32_t *pui32Addr, \ uint32_t *pui32Flags))ROM_MPUTABLE[6]) #endif //============================================================================* // // Macros for calling ROM functions in the OneWire API. // //============================================================================* #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_OneWireIntStatus \ ((uint32_t (*)(uint32_t ui32Base, \ bool bMasked))ROM_ONEWIRETABLE[0]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_OneWireBusReset \ ((void (*)(uint32_t ui32Base))ROM_ONEWIRETABLE[1]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_OneWireBusStatus \ ((uint32_t (*)(uint32_t ui32Base))ROM_ONEWIRETABLE[2]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_OneWireDataGet \ ((void (*)(uint32_t u3i2Base, \ uint32_t *pui32Data))ROM_ONEWIRETABLE[3]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_OneWireDataGetNonBlocking \ ((bool (*)(uint32_t ui32Base, \ uint32_t *pui32Data))ROM_ONEWIRETABLE[4]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_OneWireInit \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32InitFlags))ROM_ONEWIRETABLE[5]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_OneWireIntClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_ONEWIRETABLE[6]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_OneWireIntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_ONEWIRETABLE[7]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_OneWireIntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_ONEWIRETABLE[8]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_OneWireTransaction \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32OpFlags, \ uint32_t ui32Data, \ uint32_t ui32BitCnt))ROM_ONEWIRETABLE[9]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_OneWireDMADisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32DMAFlags))ROM_ONEWIRETABLE[10]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_OneWireDMAEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32DMAFlags))ROM_ONEWIRETABLE[11]) #endif //============================================================================* // // Macros for calling ROM functions in the PWM API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMPulseWidthSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32PWMOut, \ uint32_t ui32Width))ROM_PWMTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMGenConfigure \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Gen, \ uint32_t ui32Config))ROM_PWMTABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMGenPeriodSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Gen, \ uint32_t ui32Period))ROM_PWMTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMGenPeriodGet \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Gen))ROM_PWMTABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMGenEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Gen))ROM_PWMTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMGenDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Gen))ROM_PWMTABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMPulseWidthGet \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32PWMOut))ROM_PWMTABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMDeadBandEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Gen, \ uint16_t ui16Rise, \ uint16_t ui16Fall))ROM_PWMTABLE[7]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMDeadBandDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Gen))ROM_PWMTABLE[8]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMSyncUpdate \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32GenBits))ROM_PWMTABLE[9]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMSyncTimeBase \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32GenBits))ROM_PWMTABLE[10]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMOutputState \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32PWMOutBits, \ bool bEnable))ROM_PWMTABLE[11]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMOutputInvert \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32PWMOutBits, \ bool bInvert))ROM_PWMTABLE[12]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMOutputFault \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32PWMOutBits, \ bool bFaultSuppress))ROM_PWMTABLE[13]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMGenIntTrigEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Gen, \ uint32_t ui32IntTrig))ROM_PWMTABLE[14]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMGenIntTrigDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Gen, \ uint32_t ui32IntTrig))ROM_PWMTABLE[15]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMGenIntStatus \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Gen, \ bool bMasked))ROM_PWMTABLE[16]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMGenIntClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Gen, \ uint32_t ui32Ints))ROM_PWMTABLE[17]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMIntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32GenFault))ROM_PWMTABLE[18]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMIntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32GenFault))ROM_PWMTABLE[19]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMFaultIntClear \ ((void (*)(uint32_t ui32Base))ROM_PWMTABLE[20]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMIntStatus \ ((uint32_t (*)(uint32_t ui32Base, \ bool bMasked))ROM_PWMTABLE[21]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMOutputFaultLevel \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32PWMOutBits, \ bool bDriveHigh))ROM_PWMTABLE[22]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMFaultIntClearExt \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32FaultInts))ROM_PWMTABLE[23]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMGenFaultConfigure \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Gen, \ uint32_t ui32MinFaultPeriod, \ uint32_t ui32FaultSenses))ROM_PWMTABLE[24]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMGenFaultTriggerSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Gen, \ uint32_t ui32Group, \ uint32_t ui32FaultTriggers))ROM_PWMTABLE[25]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMGenFaultTriggerGet \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Gen, \ uint32_t ui32Group))ROM_PWMTABLE[26]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMGenFaultStatus \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Gen, \ uint32_t ui32Group))ROM_PWMTABLE[27]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMGenFaultClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Gen, \ uint32_t ui32Group, \ uint32_t ui32FaultTriggers))ROM_PWMTABLE[28]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMClockSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config))ROM_PWMTABLE[29]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMClockGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_PWMTABLE[30]) #endif #if defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_PWMOutputUpdateMode \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32PWMOutBits, \ uint32_t ui32Mode))ROM_PWMTABLE[31]) #endif //============================================================================* // // Macros for calling ROM functions in the QEI API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_QEIPositionGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_QEITABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_QEIEnable \ ((void (*)(uint32_t ui32Base))ROM_QEITABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_QEIDisable \ ((void (*)(uint32_t ui32Base))ROM_QEITABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_QEIConfigure \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config, \ uint32_t ui32MaxPosition))ROM_QEITABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_QEIPositionSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Position))ROM_QEITABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_QEIDirectionGet \ ((int32_t (*)(uint32_t ui32Base))ROM_QEITABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_QEIErrorGet \ ((bool (*)(uint32_t ui32Base))ROM_QEITABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_QEIVelocityEnable \ ((void (*)(uint32_t ui32Base))ROM_QEITABLE[7]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_QEIVelocityDisable \ ((void (*)(uint32_t ui32Base))ROM_QEITABLE[8]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_QEIVelocityConfigure \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32PreDiv, \ uint32_t ui32Period))ROM_QEITABLE[9]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_QEIVelocityGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_QEITABLE[10]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_QEIIntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_QEITABLE[11]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_QEIIntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_QEITABLE[12]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_QEIIntStatus \ ((uint32_t (*)(uint32_t ui32Base, \ bool bMasked))ROM_QEITABLE[13]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_QEIIntClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_QEITABLE[14]) #endif //============================================================================* // // Macros for calling ROM functions in the SHAMD5 API. // //============================================================================* #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SHAMD5IntStatus \ ((uint32_t (*)(uint32_t ui32Base, \ bool bMasked))ROM_SHAMD5TABLE[0]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SHAMD5ConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Mode))ROM_SHAMD5TABLE[1]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SHAMD5DataProcess \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32DataSrc, \ uint32_t ui32DataLength, \ uint32_t *pui32HashResult))ROM_SHAMD5TABLE[2]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SHAMD5DataWrite \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32Src))ROM_SHAMD5TABLE[3]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SHAMD5DataWriteNonBlocking \ ((bool (*)(uint32_t ui32Base, \ uint32_t *pui32Src))ROM_SHAMD5TABLE[4]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SHAMD5DMADisable \ ((void (*)(uint32_t ui32Base))ROM_SHAMD5TABLE[5]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SHAMD5DMAEnable \ ((void (*)(uint32_t ui32Base))ROM_SHAMD5TABLE[6]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SHAMD5HashLengthSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Length))ROM_SHAMD5TABLE[7]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SHAMD5HMACKeySet \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32Src))ROM_SHAMD5TABLE[8]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SHAMD5HMACPPKeyGenerate \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32Key, \ uint32_t *pui32PPKey))ROM_SHAMD5TABLE[9]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SHAMD5HMACPPKeySet \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32Src))ROM_SHAMD5TABLE[10]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SHAMD5HMACProcess \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32DataSrc, \ uint32_t ui32DataLength, \ uint32_t *pui32HashResult))ROM_SHAMD5TABLE[11]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SHAMD5IntClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_SHAMD5TABLE[12]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SHAMD5IntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_SHAMD5TABLE[13]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SHAMD5IntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_SHAMD5TABLE[14]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SHAMD5Reset \ ((void (*)(uint32_t ui32Base))ROM_SHAMD5TABLE[15]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SHAMD5ResultRead \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32Dest))ROM_SHAMD5TABLE[16]) #endif //============================================================================* // // Macros for calling ROM functions in the SMBus API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterIntProcess \ ((tSMBusStatus (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusARPDisable \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusARPEnable \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusARPUDIDPacketDecode \ ((void (*)(tSMBusUDID *pUDID, \ uint8_t *pui8Address, \ uint8_t *pui8Data))ROM_SMBUSTABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusARPUDIDPacketEncode \ ((void (*)(tSMBusUDID *pUDID, \ uint8_t ui8Address, \ uint8_t *pui8Data))ROM_SMBUSTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterARPAssignAddress \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t *pui8Data))ROM_SMBUSTABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterARPGetUDIDDir \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t ui8TargetAddress, \ uint8_t *pui8Data))ROM_SMBUSTABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterARPGetUDIDGen \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t *pui8Data))ROM_SMBUSTABLE[7]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterARPNotifyMaster \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t *pui8Data))ROM_SMBUSTABLE[8]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterARPPrepareToARP \ ((tSMBusStatus (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[9]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterARPResetDeviceDir \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t ui8TargetAddress))ROM_SMBUSTABLE[10]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterARPResetDeviceGen \ ((tSMBusStatus (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[11]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterBlockProcessCall \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t ui8TargetAddress, \ uint8_t ui8Command, \ uint8_t *pui8TxData, \ uint8_t ui8TxSize, \ uint8_t *pui8RxData))ROM_SMBUSTABLE[12]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterBlockRead \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t ui8TargetAddress, \ uint8_t ui8Command, \ uint8_t *pui8Data))ROM_SMBUSTABLE[13]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterBlockWrite \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t ui8TargetAddress, \ uint8_t ui8Command, \ uint8_t *pui8Data, \ uint8_t ui8Size))ROM_SMBUSTABLE[14]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterByteReceive \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t ui8TargetAddress, \ uint8_t *pui8Data))ROM_SMBUSTABLE[15]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterByteSend \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t ui8TargetAddress, \ uint8_t ui8Data))ROM_SMBUSTABLE[16]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterByteWordRead \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t ui8TargetAddress, \ uint8_t ui8Command, \ uint8_t *pui8Data, \ uint8_t ui8Size))ROM_SMBUSTABLE[17]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterByteWordWrite \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t ui8TargetAddress, \ uint8_t ui8Command, \ uint8_t *pui8Data, \ uint8_t ui8Size))ROM_SMBUSTABLE[18]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterHostNotify \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t ui8OwnSlaveAddress, \ uint8_t *pui8Data))ROM_SMBUSTABLE[19]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterI2CRead \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t ui8TargetAddress, \ uint8_t *pui8Data, \ uint8_t ui8Size))ROM_SMBUSTABLE[20]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterI2CWrite \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t ui8TargetAddress, \ uint8_t *pui8Data, \ uint8_t ui8Size))ROM_SMBUSTABLE[21]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterI2CWriteRead \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t ui8TargetAddress, \ uint8_t *pui8TxData, \ uint8_t ui8TxSize, \ uint8_t *pui8RxData, \ uint8_t ui8RxSize))ROM_SMBUSTABLE[22]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterInit \ ((void (*)(tSMBus *psSMBus, \ uint32_t ui32I2CBase, \ uint32_t ui32SMBusClock))ROM_SMBUSTABLE[23]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterIntEnable \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[24]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterProcessCall \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t ui8TargetAddress, \ uint8_t ui8Command, \ uint8_t *pui8TxData, \ uint8_t *pui8RxData))ROM_SMBUSTABLE[25]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusMasterQuickCommand \ ((tSMBusStatus (*)(tSMBus *psSMBus, \ uint8_t ui8TargetAddress, \ bool bData))ROM_SMBUSTABLE[26]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusPECDisable \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[27]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusPECEnable \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[28]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusRxPacketSizeGet \ ((uint8_t (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[29]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveACKSend \ ((void (*)(tSMBus *psSMBus, \ bool bACK))ROM_SMBUSTABLE[30]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveAddressSet \ ((void (*)(tSMBus *psSMBus, \ uint8_t ui8AddressNum, \ uint8_t ui8SlaveAddress))ROM_SMBUSTABLE[31]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveARPFlagARGet \ ((bool (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[32]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveARPFlagARSet \ ((void (*)(tSMBus *psSMBus, \ bool bValue))ROM_SMBUSTABLE[33]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveARPFlagAVGet \ ((bool (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[34]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveARPFlagAVSet \ ((void (*)(tSMBus *psSMBus, \ bool bValue))ROM_SMBUSTABLE[35]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveBlockTransferDisable \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[36]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveBlockTransferEnable \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[37]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveCommandGet \ ((uint8_t (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[38]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveI2CDisable \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[39]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveI2CEnable \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[40]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveInit \ ((void (*)(tSMBus *psSMBus, \ uint32_t ui32I2CBase))ROM_SMBUSTABLE[41]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveIntAddressGet \ ((tSMBusStatus (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[42]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveIntEnable \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[43]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveIntProcess \ ((tSMBusStatus (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[44]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveManualACKDisable \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[45]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveManualACKEnable \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[46]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveManualACKStatusGet \ ((bool (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[47]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveProcessCallDisable \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[48]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveProcessCallEnable \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[49]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveRxBufferSet \ ((void (*)(tSMBus *psSMBus, \ uint8_t *pui8Data, \ uint8_t ui8Size))ROM_SMBUSTABLE[50]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveTransferInit \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[51]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveTxBufferSet \ ((void (*)(tSMBus *psSMBus, \ uint8_t *pui8Data, \ uint8_t ui8Size))ROM_SMBUSTABLE[52]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveUDIDSet \ ((void (*)(tSMBus *psSMBus, \ tSMBusUDID *pUDID))ROM_SMBUSTABLE[53]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusStatusGet \ ((tSMBusStatus (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[54]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusSlaveDataSend \ ((tSMBusStatus (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[55]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusFIFOEnable \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[56]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusFIFODisable \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[57]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusDMAEnable \ ((void (*)(tSMBus *psSMBus, \ uint8_t ui8TxChannel, \ uint8_t ui8RxChannel))ROM_SMBUSTABLE[58]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SMBusDMADisable \ ((void (*)(tSMBus *psSMBus))ROM_SMBUSTABLE[59]) #endif //============================================================================* // // Macros for calling ROM functions in the SPIFlash API. // //============================================================================* #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashIntHandler \ ((uint32_t (*)(tSPIFlashState *pState))ROM_SPIFLASHTABLE[0]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashInit \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Clock, \ uint32_t ui32BitRate))ROM_SPIFLASHTABLE[1]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashWriteStatus \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8Status))ROM_SPIFLASHTABLE[2]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashPageProgram \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Addr, \ const uint8_t *pui8Data, \ uint32_t ui32Count))ROM_SPIFLASHTABLE[3]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashPageProgramNonBlocking \ ((void (*)(tSPIFlashState *pState, \ uint32_t ui32Base, \ uint32_t ui32Addr, \ const uint8_t *pui8Data, \ uint32_t ui32Count, \ bool bUseDMA, \ uint32_t ui32TxChannel))ROM_SPIFLASHTABLE[4]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashRead \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Addr, \ uint8_t *pui8Data, \ uint32_t ui32Count))ROM_SPIFLASHTABLE[5]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashReadNonBlocking \ ((void (*)(tSPIFlashState *pState, \ uint32_t ui32Base, \ uint32_t ui32Addr, \ uint8_t *pui8Data, \ uint32_t ui32Count, \ bool bUseDMA, \ uint32_t ui32TxChannel, \ uint32_t ui32RxChannel))ROM_SPIFLASHTABLE[6]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashWriteDisable \ ((void (*)(uint32_t ui32Base))ROM_SPIFLASHTABLE[7]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashReadStatus \ ((uint8_t (*)(uint32_t ui32Base))ROM_SPIFLASHTABLE[8]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashWriteEnable \ ((void (*)(uint32_t ui32Base))ROM_SPIFLASHTABLE[9]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashFastRead \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Addr, \ uint8_t *pui8Data, \ uint32_t ui32Count))ROM_SPIFLASHTABLE[10]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashFastReadNonBlocking \ ((void (*)(tSPIFlashState *pState, \ uint32_t ui32Base, \ uint32_t ui32Addr, \ uint8_t *pui8Data, \ uint32_t ui32Count, \ bool bUseDMA, \ uint32_t ui32TxChannel, \ uint32_t ui32RxChannel))ROM_SPIFLASHTABLE[11]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashSectorErase \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Addr))ROM_SPIFLASHTABLE[12]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashDualRead \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Addr, \ uint8_t *pui8Data, \ uint32_t ui32Count))ROM_SPIFLASHTABLE[13]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashDualReadNonBlocking \ ((void (*)(tSPIFlashState *pState, \ uint32_t ui32Base, \ uint32_t ui32Addr, \ uint8_t *pui8Data, \ uint32_t ui32Count, \ bool bUseDMA, \ uint32_t ui32TxChannel, \ uint32_t ui32RxChannel))ROM_SPIFLASHTABLE[14]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashBlockErase32 \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Addr))ROM_SPIFLASHTABLE[15]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashQuadRead \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Addr, \ uint8_t *pui8Data, \ uint32_t ui32Count))ROM_SPIFLASHTABLE[16]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashQuadReadNonBlocking \ ((void (*)(tSPIFlashState *pState, \ uint32_t ui32Base, \ uint32_t ui32Addr, \ uint8_t *pui8Data, \ uint32_t ui32Count, \ bool bUseDMA, \ uint32_t ui32TxChannel, \ uint32_t ui32RxChannel))ROM_SPIFLASHTABLE[17]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashReadID \ ((void (*)(uint32_t ui32Base, \ uint8_t *pui8ManufacturerID, \ uint16_t *pui16DeviceID))ROM_SPIFLASHTABLE[18]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashChipErase \ ((void (*)(uint32_t ui32Base))ROM_SPIFLASHTABLE[19]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SPIFlashBlockErase64 \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Addr))ROM_SPIFLASHTABLE[20]) #endif //============================================================================* // // Macros for calling ROM functions in the SSI API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIDataPut \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Data))ROM_SSITABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIConfigSetExpClk \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32SSIClk, \ uint32_t ui32Protocol, \ uint32_t ui32Mode, \ uint32_t ui32BitRate, \ uint32_t ui32DataWidth))ROM_SSITABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIEnable \ ((void (*)(uint32_t ui32Base))ROM_SSITABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIDisable \ ((void (*)(uint32_t ui32Base))ROM_SSITABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIIntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_SSITABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIIntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_SSITABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIIntStatus \ ((uint32_t (*)(uint32_t ui32Base, \ bool bMasked))ROM_SSITABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIIntClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_SSITABLE[7]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIDataPutNonBlocking \ ((int32_t (*)(uint32_t ui32Base, \ uint32_t ui32Data))ROM_SSITABLE[8]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIDataGet \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32Data))ROM_SSITABLE[9]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIDataGetNonBlocking \ ((int32_t (*)(uint32_t ui32Base, \ uint32_t *pui32Data))ROM_SSITABLE[10]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UpdateSSI \ ((void (*)(void))ROM_SSITABLE[11]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIDMAEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32DMAFlags))ROM_SSITABLE[12]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIDMADisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32DMAFlags))ROM_SSITABLE[13]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIBusy \ ((bool (*)(uint32_t ui32Base))ROM_SSITABLE[14]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIClockSourceGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_SSITABLE[15]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIClockSourceSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Source))ROM_SSITABLE[16]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIAdvModeSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Mode))ROM_SSITABLE[17]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIAdvDataPutFrameEnd \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Data))ROM_SSITABLE[18]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIAdvDataPutFrameEndNonBlocking \ ((int32_t (*)(uint32_t ui32Base, \ uint32_t ui32Data))ROM_SSITABLE[19]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIAdvFrameHoldEnable \ ((void (*)(uint32_t ui32Base))ROM_SSITABLE[20]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SSIAdvFrameHoldDisable \ ((void (*)(uint32_t ui32Base))ROM_SSITABLE[21]) #endif //============================================================================* // // Macros for calling ROM functions in the SysCtl API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlSleep \ ((void (*)(void))ROM_SYSCTLTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlSRAMSizeGet \ ((uint32_t (*)(void))ROM_SYSCTLTABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlFlashSizeGet \ ((uint32_t (*)(void))ROM_SYSCTLTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlPeripheralPresent \ ((bool (*)(uint32_t ui32Peripheral))ROM_SYSCTLTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlPeripheralReset \ ((void (*)(uint32_t ui32Peripheral))ROM_SYSCTLTABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlPeripheralEnable \ ((void (*)(uint32_t ui32Peripheral))ROM_SYSCTLTABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlPeripheralDisable \ ((void (*)(uint32_t ui32Peripheral))ROM_SYSCTLTABLE[7]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlPeripheralSleepEnable \ ((void (*)(uint32_t ui32Peripheral))ROM_SYSCTLTABLE[8]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlPeripheralSleepDisable \ ((void (*)(uint32_t ui32Peripheral))ROM_SYSCTLTABLE[9]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlPeripheralDeepSleepEnable \ ((void (*)(uint32_t ui32Peripheral))ROM_SYSCTLTABLE[10]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlPeripheralDeepSleepDisable \ ((void (*)(uint32_t ui32Peripheral))ROM_SYSCTLTABLE[11]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlPeripheralClockGating \ ((void (*)(bool bEnable))ROM_SYSCTLTABLE[12]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlIntEnable \ ((void (*)(uint32_t ui32Ints))ROM_SYSCTLTABLE[13]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlIntDisable \ ((void (*)(uint32_t ui32Ints))ROM_SYSCTLTABLE[14]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlIntClear \ ((void (*)(uint32_t ui32Ints))ROM_SYSCTLTABLE[15]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlIntStatus \ ((uint32_t (*)(bool bMasked))ROM_SYSCTLTABLE[16]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlReset \ ((void (*)(void))ROM_SYSCTLTABLE[19]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlDeepSleep \ ((void (*)(void))ROM_SYSCTLTABLE[20]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlResetCauseGet \ ((uint32_t (*)(void))ROM_SYSCTLTABLE[21]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlResetCauseClear \ ((void (*)(uint32_t ui32Causes))ROM_SYSCTLTABLE[22]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) #define ROM_SysCtlClockSet \ ((void (*)(uint32_t ui32Config))ROM_SYSCTLTABLE[23]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) #define ROM_SysCtlClockGet \ ((uint32_t (*)(void))ROM_SYSCTLTABLE[24]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) #define ROM_SysCtlPWMClockSet \ ((void (*)(uint32_t ui32Config))ROM_SYSCTLTABLE[25]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) #define ROM_SysCtlPWMClockGet \ ((uint32_t (*)(void))ROM_SYSCTLTABLE[26]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) #define ROM_SysCtlUSBPLLEnable \ ((void (*)(void))ROM_SYSCTLTABLE[31]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) #define ROM_SysCtlUSBPLLDisable \ ((void (*)(void))ROM_SYSCTLTABLE[32]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlDelay \ ((void (*)(uint32_t ui32Count))ROM_SYSCTLTABLE[34]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlPeripheralReady \ ((bool (*)(uint32_t ui32Peripheral))ROM_SYSCTLTABLE[35]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlPeripheralPowerOn \ ((void (*)(uint32_t ui32Peripheral))ROM_SYSCTLTABLE[36]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlPeripheralPowerOff \ ((void (*)(uint32_t ui32Peripheral))ROM_SYSCTLTABLE[37]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlMOSCConfigSet \ ((void (*)(uint32_t ui32Config))ROM_SYSCTLTABLE[44]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlPIOSCCalibrate \ ((uint32_t (*)(uint32_t ui32Type))ROM_SYSCTLTABLE[45]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) #define ROM_SysCtlDeepSleepClockSet \ ((void (*)(uint32_t ui32Config))ROM_SYSCTLTABLE[46]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlDeepSleepClockConfigSet \ ((void (*)(uint32_t ui32Div, \ uint32_t ui32Config))ROM_SYSCTLTABLE[47]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlClockFreqSet \ ((uint32_t (*)(uint32_t ui32Config, \ uint32_t ui32SysClock))ROM_SYSCTLTABLE[48]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlResetBehaviorSet \ ((void (*)(uint32_t ui32Behavior))ROM_SYSCTLTABLE[51]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlResetBehaviorGet \ ((uint32_t (*)(void))ROM_SYSCTLTABLE[52]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlFlashSectorSizeGet \ ((uint32_t (*)(void))ROM_SYSCTLTABLE[54]) #endif #if defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlVoltageEventConfig \ ((void (*)(uint32_t ui32Config))ROM_SYSCTLTABLE[55]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlVoltageEventStatus \ ((uint32_t (*)(void))ROM_SYSCTLTABLE[56]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlVoltageEventClear \ ((void (*)(uint32_t ui32Status))ROM_SYSCTLTABLE[57]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlNMIStatus \ ((uint32_t (*)(void))ROM_SYSCTLTABLE[58]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlNMIClear \ ((void (*)(uint32_t ui32Status))ROM_SYSCTLTABLE[59]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlClockOutConfig \ ((void (*)(uint32_t ui32Config, \ uint32_t ui32Div))ROM_SYSCTLTABLE[60]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysCtlAltClkConfig \ ((void (*)(uint32_t ui32Config))ROM_SYSCTLTABLE[61]) #endif //============================================================================* // // Macros for calling ROM functions in the SysExc API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysExcIntStatus \ ((uint32_t (*)(bool bMasked))ROM_SYSEXCTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysExcIntClear \ ((void (*)(uint32_t ui32IntFlags))ROM_SYSEXCTABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysExcIntDisable \ ((void (*)(uint32_t ui32IntFlags))ROM_SYSEXCTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysExcIntEnable \ ((void (*)(uint32_t ui32IntFlags))ROM_SYSEXCTABLE[3]) #endif //============================================================================* // // Macros for calling ROM functions in the SysTick API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysTickValueGet \ ((uint32_t (*)(void))ROM_SYSTICKTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysTickEnable \ ((void (*)(void))ROM_SYSTICKTABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysTickDisable \ ((void (*)(void))ROM_SYSTICKTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysTickIntEnable \ ((void (*)(void))ROM_SYSTICKTABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysTickIntDisable \ ((void (*)(void))ROM_SYSTICKTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysTickPeriodSet \ ((void (*)(uint32_t ui32Period))ROM_SYSTICKTABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_SysTickPeriodGet \ ((uint32_t (*)(void))ROM_SYSTICKTABLE[6]) #endif //============================================================================* // // Macros for calling ROM functions in the Timer API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerIntClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_TIMERTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Timer))ROM_TIMERTABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Timer))ROM_TIMERTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerConfigure \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config))ROM_TIMERTABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerControlLevel \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Timer, \ bool bInvert))ROM_TIMERTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA1) #define ROM_TimerControlTrigger \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Timer, \ bool bEnable))ROM_TIMERTABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerControlEvent \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Timer, \ uint32_t ui32Event))ROM_TIMERTABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerControlStall \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Timer, \ bool bStall))ROM_TIMERTABLE[7]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerRTCEnable \ ((void (*)(uint32_t ui32Base))ROM_TIMERTABLE[8]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerRTCDisable \ ((void (*)(uint32_t ui32Base))ROM_TIMERTABLE[9]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerPrescaleSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Timer, \ uint32_t ui32Value))ROM_TIMERTABLE[10]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerPrescaleGet \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Timer))ROM_TIMERTABLE[11]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerPrescaleMatchSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Timer, \ uint32_t ui32Value))ROM_TIMERTABLE[12]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerPrescaleMatchGet \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Timer))ROM_TIMERTABLE[13]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerLoadSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Timer, \ uint32_t ui32Value))ROM_TIMERTABLE[14]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerLoadGet \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Timer))ROM_TIMERTABLE[15]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerValueGet \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Timer))ROM_TIMERTABLE[16]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerMatchSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Timer, \ uint32_t ui32Value))ROM_TIMERTABLE[17]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerMatchGet \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Timer))ROM_TIMERTABLE[18]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerIntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_TIMERTABLE[19]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerIntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_TIMERTABLE[20]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerIntStatus \ ((uint32_t (*)(uint32_t ui32Base, \ bool bMasked))ROM_TIMERTABLE[21]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerControlWaitOnTrigger \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Timer, \ bool bWait))ROM_TIMERTABLE[22]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) #define ROM_TimerLoadSet64 \ ((void (*)(uint32_t ui32Base, \ uint64_t ui64Value))ROM_TIMERTABLE[23]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) #define ROM_TimerLoadGet64 \ ((uint64_t (*)(uint32_t ui32Base))ROM_TIMERTABLE[24]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) #define ROM_TimerValueGet64 \ ((uint64_t (*)(uint32_t ui32Base))ROM_TIMERTABLE[25]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) #define ROM_TimerMatchSet64 \ ((void (*)(uint32_t ui32Base, \ uint64_t ui64Value))ROM_TIMERTABLE[26]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) #define ROM_TimerMatchGet64 \ ((uint64_t (*)(uint32_t ui32Base))ROM_TIMERTABLE[27]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerClockSourceGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_TIMERTABLE[28]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerClockSourceSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Source))ROM_TIMERTABLE[29]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerADCEventGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_TIMERTABLE[30]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerADCEventSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32ADCEvent))ROM_TIMERTABLE[31]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerDMAEventGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_TIMERTABLE[32]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerDMAEventSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32DMAEvent))ROM_TIMERTABLE[33]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_TimerSynchronize \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Timers))ROM_TIMERTABLE[34]) #endif //============================================================================* // // Macros for calling ROM functions in the UART API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTCharPut \ ((void (*)(uint32_t ui32Base, \ unsigned char ucData))ROM_UARTTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTParityModeSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Parity))ROM_UARTTABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTParityModeGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_UARTTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTFIFOLevelSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32TxLevel, \ uint32_t ui32RxLevel))ROM_UARTTABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTFIFOLevelGet \ ((void (*)(uint32_t ui32Base, \ uint32_t *pui32TxLevel, \ uint32_t *pui32RxLevel))ROM_UARTTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTConfigSetExpClk \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32UARTClk, \ uint32_t ui32Baud, \ uint32_t ui32Config))ROM_UARTTABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTConfigGetExpClk \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32UARTClk, \ uint32_t *pui32Baud, \ uint32_t *pui32Config))ROM_UARTTABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTEnable \ ((void (*)(uint32_t ui32Base))ROM_UARTTABLE[7]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTDisable \ ((void (*)(uint32_t ui32Base))ROM_UARTTABLE[8]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTEnableSIR \ ((void (*)(uint32_t ui32Base, \ bool bLowPower))ROM_UARTTABLE[9]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTDisableSIR \ ((void (*)(uint32_t ui32Base))ROM_UARTTABLE[10]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTCharsAvail \ ((bool (*)(uint32_t ui32Base))ROM_UARTTABLE[11]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTSpaceAvail \ ((bool (*)(uint32_t ui32Base))ROM_UARTTABLE[12]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTCharGetNonBlocking \ ((int32_t (*)(uint32_t ui32Base))ROM_UARTTABLE[13]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTCharGet \ ((int32_t (*)(uint32_t ui32Base))ROM_UARTTABLE[14]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTCharPutNonBlocking \ ((bool (*)(uint32_t ui32Base, \ unsigned char ucData))ROM_UARTTABLE[15]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTBreakCtl \ ((void (*)(uint32_t ui32Base, \ bool bBreakState))ROM_UARTTABLE[16]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTIntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_UARTTABLE[17]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTIntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_UARTTABLE[18]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTIntStatus \ ((uint32_t (*)(uint32_t ui32Base, \ bool bMasked))ROM_UARTTABLE[19]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTIntClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_UARTTABLE[20]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UpdateUART \ ((void (*)(void))ROM_UARTTABLE[21]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTDMAEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32DMAFlags))ROM_UARTTABLE[22]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTDMADisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32DMAFlags))ROM_UARTTABLE[23]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTFIFOEnable \ ((void (*)(uint32_t ui32Base))ROM_UARTTABLE[24]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTFIFODisable \ ((void (*)(uint32_t ui32Base))ROM_UARTTABLE[25]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTBusy \ ((bool (*)(uint32_t ui32Base))ROM_UARTTABLE[26]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTTxIntModeSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Mode))ROM_UARTTABLE[27]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTTxIntModeGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_UARTTABLE[28]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTRxErrorGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_UARTTABLE[29]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTRxErrorClear \ ((void (*)(uint32_t ui32Base))ROM_UARTTABLE[30]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTClockSourceSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Source))ROM_UARTTABLE[31]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTClockSourceGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_UARTTABLE[32]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UART9BitEnable \ ((void (*)(uint32_t ui32Base))ROM_UARTTABLE[33]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UART9BitDisable \ ((void (*)(uint32_t ui32Base))ROM_UARTTABLE[34]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UART9BitAddrSet \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8Addr, \ uint8_t ui8Mask))ROM_UARTTABLE[35]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UART9BitAddrSend \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8Addr))ROM_UARTTABLE[36]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTSmartCardDisable \ ((void (*)(uint32_t ui32Base))ROM_UARTTABLE[37]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTSmartCardEnable \ ((void (*)(uint32_t ui32Base))ROM_UARTTABLE[38]) #endif #if defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTModemControlClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Control))ROM_UARTTABLE[39]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTModemControlGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_UARTTABLE[40]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTModemControlSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Control))ROM_UARTTABLE[41]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTModemStatusGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_UARTTABLE[42]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTFlowControlGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_UARTTABLE[43]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UARTFlowControlSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Mode))ROM_UARTTABLE[44]) #endif //============================================================================* // // Macros for calling ROM functions in the uDMA API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAChannelTransferSet \ ((void (*)(uint32_t ui32ChannelStructIndex, \ uint32_t ui32Mode, \ void *pvSrcAddr, \ void *pvDstAddr, \ uint32_t ui32TransferSize))ROM_UDMATABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAEnable \ ((void (*)(void))ROM_UDMATABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMADisable \ ((void (*)(void))ROM_UDMATABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAErrorStatusGet \ ((uint32_t (*)(void))ROM_UDMATABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAErrorStatusClear \ ((void (*)(void))ROM_UDMATABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAChannelEnable \ ((void (*)(uint32_t ui32ChannelNum))ROM_UDMATABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAChannelDisable \ ((void (*)(uint32_t ui32ChannelNum))ROM_UDMATABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAChannelIsEnabled \ ((bool (*)(uint32_t ui32ChannelNum))ROM_UDMATABLE[7]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAControlBaseSet \ ((void (*)(void *pControlTable))ROM_UDMATABLE[8]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAControlBaseGet \ ((void * (*)(void))ROM_UDMATABLE[9]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAChannelRequest \ ((void (*)(uint32_t ui32ChannelNum))ROM_UDMATABLE[10]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAChannelAttributeEnable \ ((void (*)(uint32_t ui32ChannelNum, \ uint32_t ui32Attr))ROM_UDMATABLE[11]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAChannelAttributeDisable \ ((void (*)(uint32_t ui32ChannelNum, \ uint32_t ui32Attr))ROM_UDMATABLE[12]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAChannelAttributeGet \ ((uint32_t (*)(uint32_t ui32ChannelNum))ROM_UDMATABLE[13]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAChannelControlSet \ ((void (*)(uint32_t ui32ChannelStructIndex, \ uint32_t ui32Control))ROM_UDMATABLE[14]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAChannelSizeGet \ ((uint32_t (*)(uint32_t ui32ChannelStructIndex))ROM_UDMATABLE[15]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAChannelModeGet \ ((uint32_t (*)(uint32_t ui32ChannelStructIndex))ROM_UDMATABLE[16]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAChannelSelectSecondary \ ((void (*)(uint32_t ui32SecPeriphs))ROM_UDMATABLE[17]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAChannelSelectDefault \ ((void (*)(uint32_t ui32DefPeriphs))ROM_UDMATABLE[18]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAIntStatus \ ((uint32_t (*)(void))ROM_UDMATABLE[19]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAIntClear \ ((void (*)(uint32_t ui32ChanMask))ROM_UDMATABLE[20]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAControlAlternateBaseGet \ ((void * (*)(void))ROM_UDMATABLE[21]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAChannelScatterGatherSet \ ((void (*)(uint32_t ui32ChannelNum, \ uint32_t ui32TaskCount, \ void *pvTaskList, \ uint32_t ui32IsPeriphSG))ROM_UDMATABLE[22]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_uDMAChannelAssign \ ((void (*)(uint32_t ui32Mapping))ROM_UDMATABLE[23]) #endif //============================================================================* // // Macros for calling ROM functions in the USB API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDevAddrGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_USBTABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDevAddrSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Address))ROM_USBTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDevConnect \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDevDisconnect \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDevEndpointConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32MaxPacketSize, \ uint32_t ui32Flags))ROM_USBTABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDevEndpointDataAck \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ bool bIsLastPacket))ROM_USBTABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDevEndpointStall \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32Flags))ROM_USBTABLE[7]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDevEndpointStallClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32Flags))ROM_USBTABLE[8]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDevEndpointStatusClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32Flags))ROM_USBTABLE[9]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBEndpointDataGet \ ((int32_t (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint8_t *pui8Data, \ uint32_t *pui32Size))ROM_USBTABLE[10]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBEndpointDataPut \ ((int32_t (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint8_t *pui8Data, \ uint32_t ui32Size))ROM_USBTABLE[11]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBEndpointDataSend \ ((int32_t (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32TransType))ROM_USBTABLE[12]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBEndpointDataToggleClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32Flags))ROM_USBTABLE[13]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBEndpointStatus \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint))ROM_USBTABLE[14]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBFIFOAddrGet \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint))ROM_USBTABLE[15]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBFIFOConfigGet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t *pui32FIFOAddress, \ uint32_t *pui32FIFOSize, \ uint32_t ui32Flags))ROM_USBTABLE[16]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBFIFOConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32FIFOAddress, \ uint32_t ui32FIFOSize, \ uint32_t ui32Flags))ROM_USBTABLE[17]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBFIFOFlush \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32Flags))ROM_USBTABLE[18]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBFrameNumberGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_USBTABLE[19]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostAddrGet \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32Flags))ROM_USBTABLE[20]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostAddrSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32Addr, \ uint32_t ui32Flags))ROM_USBTABLE[21]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostEndpointConfig \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32MaxPacketSize, \ uint32_t ui32NAKPollInterval, \ uint32_t ui32TargetEndpoint, \ uint32_t ui32Flags))ROM_USBTABLE[22]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostEndpointDataAck \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint))ROM_USBTABLE[23]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostEndpointDataToggle \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ bool bDataToggle, \ uint32_t ui32Flags))ROM_USBTABLE[24]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostEndpointStatusClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32Flags))ROM_USBTABLE[25]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostHubAddrGet \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32Flags))ROM_USBTABLE[26]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostHubAddrSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32Addr, \ uint32_t ui32Flags))ROM_USBTABLE[27]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostPwrDisable \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[28]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostPwrEnable \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[29]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostPwrConfig \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Flags))ROM_USBTABLE[30]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostPwrFaultDisable \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[31]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostPwrFaultEnable \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[32]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostRequestIN \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint))ROM_USBTABLE[33]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostRequestStatus \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[34]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostReset \ ((void (*)(uint32_t ui32Base, \ bool bStart))ROM_USBTABLE[35]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostResume \ ((void (*)(uint32_t ui32Base, \ bool bStart))ROM_USBTABLE[36]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostSpeedGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_USBTABLE[37]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostSuspend \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[38]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDevEndpointConfigGet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t *pui32MaxPacketSize, \ uint32_t *pui32Flags))ROM_USBTABLE[41]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBEndpointDMAEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32Flags))ROM_USBTABLE[42]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBEndpointDMADisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32Flags))ROM_USBTABLE[43]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBEndpointDataAvail \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint))ROM_USBTABLE[44]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBModeGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_USBTABLE[46]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBEndpointDMAChannel \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32Channel))ROM_USBTABLE[47]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBIntDisableControl \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_USBTABLE[48]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBIntEnableControl \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_USBTABLE[49]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBIntStatusControl \ ((uint32_t (*)(uint32_t ui32Base))ROM_USBTABLE[50]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBIntDisableEndpoint \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_USBTABLE[51]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBIntEnableEndpoint \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32IntFlags))ROM_USBTABLE[52]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBIntStatusEndpoint \ ((uint32_t (*)(uint32_t ui32Base))ROM_USBTABLE[53]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostMode \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[54]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDevMode \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[55]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBPHYPowerOff \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[56]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBPHYPowerOn \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[57]) #endif #if defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_UpdateUSB \ ((void (*)(uint8_t *pui8DescriptorInfo))ROM_USBTABLE[58]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBOTGMode \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[59]) #endif #if defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostRequestINClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint))ROM_USBTABLE[60]) #endif #if defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBNumEndpointsGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_USBTABLE[61]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBClockDisable \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[62]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBClockEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Div, \ uint32_t ui32Flags))ROM_USBTABLE[63]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBControllerVersion \ ((uint32_t (*)(uint32_t ui32Base))ROM_USBTABLE[64]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDevLPMConfig \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config))ROM_USBTABLE[65]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDevLPMDisable \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[66]) #endif #if defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDevLPMEnable \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[67]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDevLPMRemoteWake \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[68]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDevSpeedGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_USBTABLE[69]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDMAChannelAddressGet \ ((void * (*)(uint32_t ui32Base, \ uint32_t ui32Channel))ROM_USBTABLE[70]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDMAChannelAddressSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Channel, \ void *pvAddress))ROM_USBTABLE[71]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDMAChannelConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Channel, \ uint32_t ui32Endpoint, \ uint32_t ui32Config))ROM_USBTABLE[72]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDMAChannelDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Channel))ROM_USBTABLE[73]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDMAChannelEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Channel))ROM_USBTABLE[74]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDMAChannelIntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Channel))ROM_USBTABLE[75]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDMAChannelIntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Channel))ROM_USBTABLE[76]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDMAChannelCountGet \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Channel))ROM_USBTABLE[77]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDMAChannelCountSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Count, \ uint32_t ui32Channel))ROM_USBTABLE[78]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDMAChannelIntStatus \ ((uint32_t (*)(uint32_t ui32Base))ROM_USBTABLE[79]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDMAChannelStatus \ ((uint32_t (*)(uint32_t ui32Base, \ uint32_t ui32Channel))ROM_USBTABLE[80]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDMAChannelStatusClear \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Channel, \ uint32_t ui32Status))ROM_USBTABLE[81]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHighSpeed \ ((void (*)(uint32_t ui32Base, \ bool bEnable))ROM_USBTABLE[82]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostEndpointPing \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ bool bEnable))ROM_USBTABLE[83]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostEndpointSpeed \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32Flags))ROM_USBTABLE[84]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostLPMConfig \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32ResumeTime, \ uint32_t ui32Config))ROM_USBTABLE[85]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostLPMResume \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[86]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBHostLPMSend \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Address, \ uint32_t uiEndpoint))ROM_USBTABLE[87]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBLPMIntDisable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Ints))ROM_USBTABLE[88]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBLPMIntEnable \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Ints))ROM_USBTABLE[89]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBLPMIntStatus \ ((uint32_t (*)(uint32_t ui32Base))ROM_USBTABLE[90]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBLPMLinkStateGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_USBTABLE[91]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBEndpointPacketCountSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32Count))ROM_USBTABLE[92]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBULPIConfig \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Config))ROM_USBTABLE[93]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBULPIDisable \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[94]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBULPIEnable \ ((void (*)(uint32_t ui32Base))ROM_USBTABLE[95]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBULPIRegRead \ ((uint8_t (*)(uint32_t ui32Base, \ uint8_t ui8Reg))ROM_USBTABLE[96]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBULPIRegWrite \ ((void (*)(uint32_t ui32Base, \ uint8_t ui8Reg, \ uint8_t ui8Data))ROM_USBTABLE[97]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBOTGSessionRequest \ ((void (*)(uint32_t ui32Base, \ bool bStart))ROM_USBTABLE[98]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBDMANumChannels \ ((uint32_t (*)(uint32_t ui32Base))ROM_USBTABLE[99]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBEndpointDMAConfigSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Endpoint, \ uint32_t ui32Config))ROM_USBTABLE[100]) #endif #if defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBLPMRemoteWakeEnabled \ ((bool (*)(uint32_t ui32Base))ROM_USBTABLE[102]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_USBModeConfig \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Mode))ROM_USBTABLE[103]) #endif //============================================================================* // // Macros for calling ROM functions in the Watchdog API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_WatchdogIntClear \ ((void (*)(uint32_t ui32Base))ROM_WATCHDOGTABLE[0]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_WatchdogRunning \ ((bool (*)(uint32_t ui32Base))ROM_WATCHDOGTABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_WatchdogEnable \ ((void (*)(uint32_t ui32Base))ROM_WATCHDOGTABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_WatchdogResetEnable \ ((void (*)(uint32_t ui32Base))ROM_WATCHDOGTABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_WatchdogResetDisable \ ((void (*)(uint32_t ui32Base))ROM_WATCHDOGTABLE[4]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_WatchdogLock \ ((void (*)(uint32_t ui32Base))ROM_WATCHDOGTABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_WatchdogUnlock \ ((void (*)(uint32_t ui32Base))ROM_WATCHDOGTABLE[6]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_WatchdogLockState \ ((bool (*)(uint32_t ui32Base))ROM_WATCHDOGTABLE[7]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_WatchdogReloadSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32LoadVal))ROM_WATCHDOGTABLE[8]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_WatchdogReloadGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_WATCHDOGTABLE[9]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_WatchdogValueGet \ ((uint32_t (*)(uint32_t ui32Base))ROM_WATCHDOGTABLE[10]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_WatchdogIntEnable \ ((void (*)(uint32_t ui32Base))ROM_WATCHDOGTABLE[11]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_WatchdogIntStatus \ ((uint32_t (*)(uint32_t ui32Base, \ bool bMasked))ROM_WATCHDOGTABLE[12]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_WatchdogStallEnable \ ((void (*)(uint32_t ui32Base))ROM_WATCHDOGTABLE[13]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_WatchdogStallDisable \ ((void (*)(uint32_t ui32Base))ROM_WATCHDOGTABLE[14]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_WatchdogIntTypeSet \ ((void (*)(uint32_t ui32Base, \ uint32_t ui32Type))ROM_WATCHDOGTABLE[15]) #endif //============================================================================* // // Macros for calling ROM functions in the Software API. // //============================================================================* #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_Crc16Array \ ((uint16_t (*)(uint32_t ui32WordLen, \ const uint32_t *pui32Data))ROM_SOFTWARETABLE[1]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_Crc16Array3 \ ((void (*)(uint32_t ui32WordLen, \ const uint32_t *pui32Data, \ uint16_t *pui16Crc3))ROM_SOFTWARETABLE[2]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_Crc16 \ ((uint16_t (*)(uint16_t ui16Crc, \ const uint8_t *pui8Data, \ uint32_t ui32Count))ROM_SOFTWARETABLE[3]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_Crc8CCITT \ ((uint8_t (*)(uint8_t ui8Crc, \ const uint8_t *pui8Data, \ uint32_t ui32Count))ROM_SOFTWARETABLE[4]) #endif #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_Crc32 \ ((uint32_t (*)(uint32_t ui32Crc, \ const uint8_t *pui8Data, \ uint32_t ui32Count))ROM_SOFTWARETABLE[5]) #endif #if defined(TARGET_IS_TM4C123_RA1) || \ defined(TARGET_IS_TM4C123_RA3) || \ defined(TARGET_IS_TM4C123_RB1) || \ defined(TARGET_IS_TM4C123_RB2) || \ defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define ROM_pvAESTable \ ((void *)&(ROM_SOFTWARETABLE[7])) #endif #endif // __DRIVERLIB_ROM_H__ ================================================ FILE: 3rd_party/ek-tm4c123gxl/sysctl.h ================================================ //============================================================================* // // sysctl.h - Prototypes for the system control driver. // // Copyright (c) 2005-2012 Texas Instruments Incorporated. All rights reserved. // Software License Agreement // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // This is part of revision 9453 of the Stellaris Peripheral Driver Library. // //============================================================================* #ifndef __SYSCTL_H__ #define __SYSCTL_H__ //============================================================================* // // If building with a C++ compiler, make all of the definitions in this header // have a C binding. // //============================================================================* #ifdef __cplusplus extern "C" { #endif typedef unsigned char tBoolean; //============================================================================* // // The following are values that can be passed to the // SysCtlPeripheralPresent(), SysCtlPeripheralEnable(), // SysCtlPeripheralDisable(), and SysCtlPeripheralReset() APIs as the // ulPeripheral parameter. The peripherals in the fourth group (upper nibble // is 3) can only be used with the SysCtlPeripheralPresent() API. // //============================================================================* #ifndef DEPRECATED #define SYSCTL_PERIPH_WDOG 0x00000008 // Watchdog #endif #define SYSCTL_PERIPH_WDOG0 0x00000008 // Watchdog 0 #define SYSCTL_PERIPH_HIBERNATE 0x00000040 // Hibernation module #ifndef DEPRECATED #define SYSCTL_PERIPH_ADC 0x00100001 // ADC #endif #define SYSCTL_PERIPH_ADC0 0x00100001 // ADC0 #define SYSCTL_PERIPH_ADC1 0x00100002 // ADC1 #ifndef DEPRECATED #define SYSCTL_PERIPH_PWM 0x00100010 // PWM #endif #define SYSCTL_PERIPH_PWM0 0x00100010 // PWM #define SYSCTL_PERIPH_CAN0 0x00100100 // CAN 0 #define SYSCTL_PERIPH_CAN1 0x00100200 // CAN 1 #define SYSCTL_PERIPH_CAN2 0x00100400 // CAN 2 #define SYSCTL_PERIPH_WDOG1 0x00101000 // Watchdog 1 #define SYSCTL_PERIPH_UART0 0x10000001 // UART 0 #define SYSCTL_PERIPH_UART1 0x10000002 // UART 1 #define SYSCTL_PERIPH_UART2 0x10000004 // UART 2 #ifndef DEPRECATED #define SYSCTL_PERIPH_SSI 0x10000010 // SSI #endif #define SYSCTL_PERIPH_SSI0 0x10000010 // SSI 0 #define SYSCTL_PERIPH_SSI1 0x10000020 // SSI 1 #ifndef DEPRECATED #define SYSCTL_PERIPH_QEI 0x10000100 // QEI #endif #define SYSCTL_PERIPH_QEI0 0x10000100 // QEI 0 #define SYSCTL_PERIPH_QEI1 0x10000200 // QEI 1 #ifndef DEPRECATED #define SYSCTL_PERIPH_I2C 0x10001000 // I2C #endif #define SYSCTL_PERIPH_I2C0 0x10001000 // I2C 0 #define SYSCTL_PERIPH_I2C1 0x10004000 // I2C 1 #define SYSCTL_PERIPH_TIMER0 0x10100001 // Timer 0 #define SYSCTL_PERIPH_TIMER1 0x10100002 // Timer 1 #define SYSCTL_PERIPH_TIMER2 0x10100004 // Timer 2 #define SYSCTL_PERIPH_TIMER3 0x10100008 // Timer 3 #define SYSCTL_PERIPH_COMP0 0x10100100 // Analog comparator 0 #define SYSCTL_PERIPH_COMP1 0x10100200 // Analog comparator 1 #define SYSCTL_PERIPH_COMP2 0x10100400 // Analog comparator 2 #define SYSCTL_PERIPH_I2S0 0x10101000 // I2S0 #define SYSCTL_PERIPH_EPI0 0x10104000 // EPI0 #define SYSCTL_PERIPH_GPIOA 0x20000001 // GPIO A #define SYSCTL_PERIPH_GPIOB 0x20000002 // GPIO B #define SYSCTL_PERIPH_GPIOC 0x20000004 // GPIO C #define SYSCTL_PERIPH_GPIOD 0x20000008 // GPIO D #define SYSCTL_PERIPH_GPIOE 0x20000010 // GPIO E #define SYSCTL_PERIPH_GPIOF 0x20000020 // GPIO F #define SYSCTL_PERIPH_GPIOG 0x20000040 // GPIO G #define SYSCTL_PERIPH_GPIOH 0x20000080 // GPIO H #define SYSCTL_PERIPH_GPIOJ 0x20000100 // GPIO J #define SYSCTL_PERIPH_UDMA 0x20002000 // uDMA #define SYSCTL_PERIPH_USB0 0x20100001 // USB0 #define SYSCTL_PERIPH_ETH 0x20105000 // Ethernet #define SYSCTL_PERIPH_IEEE1588 0x20100100 // IEEE1588 #define SYSCTL_PERIPH_PLL 0x30000010 // PLL #define SYSCTL_PERIPH_TEMP 0x30000020 // Temperature sensor #define SYSCTL_PERIPH_MPU 0x30000080 // Cortex M3 MPU #define SYSCTL_PERIPH2_ADC0 0xf0003800 // ADC 0 #define SYSCTL_PERIPH2_ADC1 0xf0003801 // ADC 1 #define SYSCTL_PERIPH2_CAN0 0xf0003400 // CAN 0 #define SYSCTL_PERIPH2_CAN1 0xf0003401 // CAN 1 #define SYSCTL_PERIPH2_CAN2 0xf0003402 // CAN 2 #define SYSCTL_PERIPH2_COMP0 0xf0003c00 // Analog comparator 0 #define SYSCTL_PERIPH_EEPROM0 0xf0005800 // EEPROM 0 #define SYSCTL_PERIPH2_EPI0 0xf0001000 // EPI0 #define SYSCTL_PERIPH2_ETH 0xf0002c00 // ETH #define SYSCTL_PERIPH_FAN0 0xf0005400 // FAN 0 #define SYSCTL_PERIPH2_GPIOA 0xf0000800 // GPIO A #define SYSCTL_PERIPH2_GPIOB 0xf0000801 // GPIO B #define SYSCTL_PERIPH2_GPIOC 0xf0000802 // GPIO C #define SYSCTL_PERIPH2_GPIOD 0xf0000803 // GPIO D #define SYSCTL_PERIPH2_GPIOE 0xf0000804 // GPIO E #define SYSCTL_PERIPH2_GPIOF 0xf0000805 // GPIO F #define SYSCTL_PERIPH2_GPIOG 0xf0000806 // GPIO G #define SYSCTL_PERIPH2_GPIOH 0xf0000807 // GPIO H #define SYSCTL_PERIPH2_GPIOJ 0xf0000808 // GPIO J #define SYSCTL_PERIPH_GPIOK 0xf0000809 // GPIO K #define SYSCTL_PERIPH_GPIOL 0xf000080a // GPIO L #define SYSCTL_PERIPH_GPIOM 0xf000080b // GPIO M #define SYSCTL_PERIPH_GPION 0xf000080c // GPIO N #define SYSCTL_PERIPH_GPIOP 0xf000080d // GPIO P #define SYSCTL_PERIPH_GPIOQ 0xf000080e // GPIO Q #define SYSCTL_PERIPH_GPIOR 0xf000080f // GPIO R #define SYSCTL_PERIPH_GPIOS 0xf0000810 // GPIO S #define SYSCTL_PERIPH2_HIB 0xf0001400 // Hibernation module #define SYSCTL_PERIPH2_I2C0 0xf0002000 // I2C 0 #define SYSCTL_PERIPH2_I2C1 0xf0002001 // I2C 1 #define SYSCTL_PERIPH_I2C2 0xf0002002 // I2C 2 #define SYSCTL_PERIPH_I2C3 0xf0002003 // I2C 3 #define SYSCTL_PERIPH_I2C4 0xf0002004 // I2C 4 #define SYSCTL_PERIPH_I2C5 0xf0002005 // I2C 5 #define SYSCTL_PERIPH2_I2S0 0xf0002400 // I2S0 #define SYSCTL_PERIPH_LPC0 0xf0004800 // LPC 0 #define SYSCTL_PERIPH_PECI0 0xf0005000 // PECI 0 #define SYSCTL_PERIPH2_PWM0 0xf0004000 // PWM 0 #define SYSCTL_PERIPH_PWM1 0xf0004001 // PWM 1 #define SYSCTL_PERIPH2_QEI0 0xf0004400 // QEI 0 #define SYSCTL_PERIPH2_QEI1 0xf0004401 // QEI 1 #define SYSCTL_PERIPH2_SSI0 0xf0001c00 // SSI 0 #define SYSCTL_PERIPH2_SSI1 0xf0001c01 // SSI 1 #define SYSCTL_PERIPH_SSI2 0xf0001c02 // SSI 2 #define SYSCTL_PERIPH_SSI3 0xf0001c03 // SSI 3 #define SYSCTL_PERIPH2_TIMER0 0xf0000400 // Timer 0 #define SYSCTL_PERIPH2_TIMER1 0xf0000401 // Timer 1 #define SYSCTL_PERIPH2_TIMER2 0xf0000402 // Timer 2 #define SYSCTL_PERIPH2_TIMER3 0xf0000403 // Timer 3 #define SYSCTL_PERIPH_TIMER4 0xf0000404 // Timer 4 #define SYSCTL_PERIPH_TIMER5 0xf0000405 // Timer 5 #define SYSCTL_PERIPH_WTIMER0 0xf0005c00 // Wide Timer 0 #define SYSCTL_PERIPH_WTIMER1 0xf0005c01 // Wide Timer 1 #define SYSCTL_PERIPH_WTIMER2 0xf0005c02 // Wide Timer 2 #define SYSCTL_PERIPH_WTIMER3 0xf0005c03 // Wide Timer 3 #define SYSCTL_PERIPH_WTIMER4 0xf0005c04 // Wide Timer 4 #define SYSCTL_PERIPH_WTIMER5 0xf0005c05 // Wide Timer 5 #define SYSCTL_PERIPH2_UART0 0xf0001800 // UART 0 #define SYSCTL_PERIPH2_UART1 0xf0001801 // UART 1 #define SYSCTL_PERIPH2_UART2 0xf0001802 // UART 2 #define SYSCTL_PERIPH_UART3 0xf0001803 // UART 3 #define SYSCTL_PERIPH_UART4 0xf0001804 // UART 4 #define SYSCTL_PERIPH_UART5 0xf0001805 // UART 5 #define SYSCTL_PERIPH_UART6 0xf0001806 // UART 6 #define SYSCTL_PERIPH_UART7 0xf0001807 // UART 7 #define SYSCTL_PERIPH2_UDMA 0xf0000c00 // uDMA #define SYSCTL_PERIPH2_USB0 0xf0002800 // USB 0 #define SYSCTL_PERIPH2_WDOG0 0xf0000000 // Watchdog 0 #define SYSCTL_PERIPH2_WDOG1 0xf0000001 // Watchdog 1 #define SYSCTL_PERIPH2_HIBERNATE \ 0xf0001400 // Hibernate //============================================================================* // // The following are values that can be passed to the SysCtlPinPresent() API // as the ulPin parameter. // //============================================================================* #define SYSCTL_PIN_PWM0 0x00000001 // PWM0 pin #define SYSCTL_PIN_PWM1 0x00000002 // PWM1 pin #define SYSCTL_PIN_PWM2 0x00000004 // PWM2 pin #define SYSCTL_PIN_PWM3 0x00000008 // PWM3 pin #define SYSCTL_PIN_PWM4 0x00000010 // PWM4 pin #define SYSCTL_PIN_PWM5 0x00000020 // PWM5 pin #define SYSCTL_PIN_PWM6 0x00000040 // PWM6 pin #define SYSCTL_PIN_PWM7 0x00000080 // PWM7 pin #define SYSCTL_PIN_C0MINUS 0x00000040 // C0- pin #define SYSCTL_PIN_C0PLUS 0x00000080 // C0+ pin #define SYSCTL_PIN_C0O 0x00000100 // C0o pin #define SYSCTL_PIN_C1MINUS 0x00000200 // C1- pin #define SYSCTL_PIN_C1PLUS 0x00000400 // C1+ pin #define SYSCTL_PIN_C1O 0x00000800 // C1o pin #define SYSCTL_PIN_C2MINUS 0x00001000 // C2- pin #define SYSCTL_PIN_C2PLUS 0x00002000 // C2+ pin #define SYSCTL_PIN_C2O 0x00004000 // C2o pin #define SYSCTL_PIN_MC_FAULT0 0x00008000 // MC0 Fault pin #define SYSCTL_PIN_ADC0 0x00010000 // ADC0 pin #define SYSCTL_PIN_ADC1 0x00020000 // ADC1 pin #define SYSCTL_PIN_ADC2 0x00040000 // ADC2 pin #define SYSCTL_PIN_ADC3 0x00080000 // ADC3 pin #define SYSCTL_PIN_ADC4 0x00100000 // ADC4 pin #define SYSCTL_PIN_ADC5 0x00200000 // ADC5 pin #define SYSCTL_PIN_ADC6 0x00400000 // ADC6 pin #define SYSCTL_PIN_ADC7 0x00800000 // ADC7 pin #define SYSCTL_PIN_CCP0 0x01000000 // CCP0 pin #define SYSCTL_PIN_CCP1 0x02000000 // CCP1 pin #define SYSCTL_PIN_CCP2 0x04000000 // CCP2 pin #define SYSCTL_PIN_CCP3 0x08000000 // CCP3 pin #define SYSCTL_PIN_CCP4 0x10000000 // CCP4 pin #define SYSCTL_PIN_CCP5 0x20000000 // CCP5 pin #define SYSCTL_PIN_32KHZ 0x80000000 // 32kHz pin //============================================================================* // // The following are values that can be passed to the SysCtlLDOSet() API as // the ulVoltage value, or returned by the SysCtlLDOGet() API. // //============================================================================* #define SYSCTL_LDO_2_25V 0x00000005 // LDO output of 2.25V #define SYSCTL_LDO_2_30V 0x00000004 // LDO output of 2.30V #define SYSCTL_LDO_2_35V 0x00000003 // LDO output of 2.35V #define SYSCTL_LDO_2_40V 0x00000002 // LDO output of 2.40V #define SYSCTL_LDO_2_45V 0x00000001 // LDO output of 2.45V #define SYSCTL_LDO_2_50V 0x00000000 // LDO output of 2.50V #define SYSCTL_LDO_2_55V 0x0000001f // LDO output of 2.55V #define SYSCTL_LDO_2_60V 0x0000001e // LDO output of 2.60V #define SYSCTL_LDO_2_65V 0x0000001d // LDO output of 2.65V #define SYSCTL_LDO_2_70V 0x0000001c // LDO output of 2.70V #define SYSCTL_LDO_2_75V 0x0000001b // LDO output of 2.75V //============================================================================* // // The following are values that can be passed to the SysCtlLDOConfigSet() API. // //============================================================================* #define SYSCTL_LDOCFG_ARST 0x00000001 // Allow LDO failure to reset #define SYSCTL_LDOCFG_NORST 0x00000000 // Do not reset on LDO failure //============================================================================* // // The following are values that can be passed to the SysCtlIntEnable(), // SysCtlIntDisable(), and SysCtlIntClear() APIs, or returned in the bit mask // by the SysCtlIntStatus() API. // //============================================================================* #define SYSCTL_INT_MOSC_PUP 0x00000100 // MOSC power-up interrupt #define SYSCTL_INT_USBPLL_LOCK 0x00000080 // USB PLL lock interrupt #define SYSCTL_INT_PLL_LOCK 0x00000040 // PLL lock interrupt #define SYSCTL_INT_CUR_LIMIT 0x00000020 // Current limit interrupt #define SYSCTL_INT_IOSC_FAIL 0x00000010 // Internal oscillator failure int #define SYSCTL_INT_MOSC_FAIL 0x00000008 // Main oscillator failure int #define SYSCTL_INT_POR 0x00000004 // Power on reset interrupt #define SYSCTL_INT_BOR 0x00000002 // Brown out interrupt #define SYSCTL_INT_PLL_FAIL 0x00000001 // PLL failure interrupt //============================================================================* // // The following are values that can be passed to the SysCtlResetCauseClear() // API or returned by the SysCtlResetCauseGet() API. // //============================================================================* #define SYSCTL_CAUSE_LDO 0x00000020 // LDO power not OK reset #define SYSCTL_CAUSE_WDOG1 0x00000020 // Watchdog 1 reset #define SYSCTL_CAUSE_SW 0x00000010 // Software reset #define SYSCTL_CAUSE_WDOG0 0x00000008 // Watchdog 0 reset #define SYSCTL_CAUSE_WDOG 0x00000008 // Watchdog reset #define SYSCTL_CAUSE_BOR 0x00000004 // Brown-out reset #define SYSCTL_CAUSE_POR 0x00000002 // Power on reset #define SYSCTL_CAUSE_EXT 0x00000001 // External reset //============================================================================* // // The following are values that can be passed to the SysCtlBrownOutConfigSet() // API as the ulConfig parameter. // //============================================================================* #define SYSCTL_BOR_RESET 0x00000002 // Reset instead of interrupting #define SYSCTL_BOR_RESAMPLE 0x00000001 // Resample BOR before asserting //============================================================================* // // The following are values that can be passed to the SysCtlPWMClockSet() API // as the ulConfig parameter, and can be returned by the SysCtlPWMClockGet() // API. // //============================================================================* #define SYSCTL_PWMDIV_1 0x00000000 // PWM clock is processor clock /1 #define SYSCTL_PWMDIV_2 0x00100000 // PWM clock is processor clock /2 #define SYSCTL_PWMDIV_4 0x00120000 // PWM clock is processor clock /4 #define SYSCTL_PWMDIV_8 0x00140000 // PWM clock is processor clock /8 #define SYSCTL_PWMDIV_16 0x00160000 // PWM clock is processor clock /16 #define SYSCTL_PWMDIV_32 0x00180000 // PWM clock is processor clock /32 #define SYSCTL_PWMDIV_64 0x001A0000 // PWM clock is processor clock /64 //============================================================================* // // The following are values that can be passed to the SysCtlADCSpeedSet() API // as the ulSpeed parameter, and can be returned by the SyCtlADCSpeedGet() // API. // //============================================================================* #define SYSCTL_ADCSPEED_1MSPS 0x00000F00 // 1,000,000 samples per second #define SYSCTL_ADCSPEED_500KSPS 0x00000A00 // 500,000 samples per second #define SYSCTL_ADCSPEED_250KSPS 0x00000500 // 250,000 samples per second #define SYSCTL_ADCSPEED_125KSPS 0x00000000 // 125,000 samples per second //============================================================================* // // The following are values that can be passed to the SysCtlClockSet() API as // the ulConfig parameter. // //============================================================================* #define SYSCTL_SYSDIV_1 0x07800000 // Processor clock is osc/pll /1 #define SYSCTL_SYSDIV_2 0x00C00000 // Processor clock is osc/pll /2 #define SYSCTL_SYSDIV_3 0x01400000 // Processor clock is osc/pll /3 #define SYSCTL_SYSDIV_4 0x01C00000 // Processor clock is osc/pll /4 #define SYSCTL_SYSDIV_5 0x02400000 // Processor clock is osc/pll /5 #define SYSCTL_SYSDIV_6 0x02C00000 // Processor clock is osc/pll /6 #define SYSCTL_SYSDIV_7 0x03400000 // Processor clock is osc/pll /7 #define SYSCTL_SYSDIV_8 0x03C00000 // Processor clock is osc/pll /8 #define SYSCTL_SYSDIV_9 0x04400000 // Processor clock is osc/pll /9 #define SYSCTL_SYSDIV_10 0x04C00000 // Processor clock is osc/pll /10 #define SYSCTL_SYSDIV_11 0x05400000 // Processor clock is osc/pll /11 #define SYSCTL_SYSDIV_12 0x05C00000 // Processor clock is osc/pll /12 #define SYSCTL_SYSDIV_13 0x06400000 // Processor clock is osc/pll /13 #define SYSCTL_SYSDIV_14 0x06C00000 // Processor clock is osc/pll /14 #define SYSCTL_SYSDIV_15 0x07400000 // Processor clock is osc/pll /15 #define SYSCTL_SYSDIV_16 0x07C00000 // Processor clock is osc/pll /16 #define SYSCTL_SYSDIV_17 0x88400000 // Processor clock is osc/pll /17 #define SYSCTL_SYSDIV_18 0x88C00000 // Processor clock is osc/pll /18 #define SYSCTL_SYSDIV_19 0x89400000 // Processor clock is osc/pll /19 #define SYSCTL_SYSDIV_20 0x89C00000 // Processor clock is osc/pll /20 #define SYSCTL_SYSDIV_21 0x8A400000 // Processor clock is osc/pll /21 #define SYSCTL_SYSDIV_22 0x8AC00000 // Processor clock is osc/pll /22 #define SYSCTL_SYSDIV_23 0x8B400000 // Processor clock is osc/pll /23 #define SYSCTL_SYSDIV_24 0x8BC00000 // Processor clock is osc/pll /24 #define SYSCTL_SYSDIV_25 0x8C400000 // Processor clock is osc/pll /25 #define SYSCTL_SYSDIV_26 0x8CC00000 // Processor clock is osc/pll /26 #define SYSCTL_SYSDIV_27 0x8D400000 // Processor clock is osc/pll /27 #define SYSCTL_SYSDIV_28 0x8DC00000 // Processor clock is osc/pll /28 #define SYSCTL_SYSDIV_29 0x8E400000 // Processor clock is osc/pll /29 #define SYSCTL_SYSDIV_30 0x8EC00000 // Processor clock is osc/pll /30 #define SYSCTL_SYSDIV_31 0x8F400000 // Processor clock is osc/pll /31 #define SYSCTL_SYSDIV_32 0x8FC00000 // Processor clock is osc/pll /32 #define SYSCTL_SYSDIV_33 0x90400000 // Processor clock is osc/pll /33 #define SYSCTL_SYSDIV_34 0x90C00000 // Processor clock is osc/pll /34 #define SYSCTL_SYSDIV_35 0x91400000 // Processor clock is osc/pll /35 #define SYSCTL_SYSDIV_36 0x91C00000 // Processor clock is osc/pll /36 #define SYSCTL_SYSDIV_37 0x92400000 // Processor clock is osc/pll /37 #define SYSCTL_SYSDIV_38 0x92C00000 // Processor clock is osc/pll /38 #define SYSCTL_SYSDIV_39 0x93400000 // Processor clock is osc/pll /39 #define SYSCTL_SYSDIV_40 0x93C00000 // Processor clock is osc/pll /40 #define SYSCTL_SYSDIV_41 0x94400000 // Processor clock is osc/pll /41 #define SYSCTL_SYSDIV_42 0x94C00000 // Processor clock is osc/pll /42 #define SYSCTL_SYSDIV_43 0x95400000 // Processor clock is osc/pll /43 #define SYSCTL_SYSDIV_44 0x95C00000 // Processor clock is osc/pll /44 #define SYSCTL_SYSDIV_45 0x96400000 // Processor clock is osc/pll /45 #define SYSCTL_SYSDIV_46 0x96C00000 // Processor clock is osc/pll /46 #define SYSCTL_SYSDIV_47 0x97400000 // Processor clock is osc/pll /47 #define SYSCTL_SYSDIV_48 0x97C00000 // Processor clock is osc/pll /48 #define SYSCTL_SYSDIV_49 0x98400000 // Processor clock is osc/pll /49 #define SYSCTL_SYSDIV_50 0x98C00000 // Processor clock is osc/pll /50 #define SYSCTL_SYSDIV_51 0x99400000 // Processor clock is osc/pll /51 #define SYSCTL_SYSDIV_52 0x99C00000 // Processor clock is osc/pll /52 #define SYSCTL_SYSDIV_53 0x9A400000 // Processor clock is osc/pll /53 #define SYSCTL_SYSDIV_54 0x9AC00000 // Processor clock is osc/pll /54 #define SYSCTL_SYSDIV_55 0x9B400000 // Processor clock is osc/pll /55 #define SYSCTL_SYSDIV_56 0x9BC00000 // Processor clock is osc/pll /56 #define SYSCTL_SYSDIV_57 0x9C400000 // Processor clock is osc/pll /57 #define SYSCTL_SYSDIV_58 0x9CC00000 // Processor clock is osc/pll /58 #define SYSCTL_SYSDIV_59 0x9D400000 // Processor clock is osc/pll /59 #define SYSCTL_SYSDIV_60 0x9DC00000 // Processor clock is osc/pll /60 #define SYSCTL_SYSDIV_61 0x9E400000 // Processor clock is osc/pll /61 #define SYSCTL_SYSDIV_62 0x9EC00000 // Processor clock is osc/pll /62 #define SYSCTL_SYSDIV_63 0x9F400000 // Processor clock is osc/pll /63 #define SYSCTL_SYSDIV_64 0x9FC00000 // Processor clock is osc/pll /64 #define SYSCTL_SYSDIV_2_5 0xC1000000 // Processor clock is pll / 2.5 #define SYSCTL_SYSDIV_3_5 0xC1800000 // Processor clock is pll / 3.5 #define SYSCTL_SYSDIV_4_5 0xC2000000 // Processor clock is pll / 4.5 #define SYSCTL_SYSDIV_5_5 0xC2800000 // Processor clock is pll / 5.5 #define SYSCTL_SYSDIV_6_5 0xC3000000 // Processor clock is pll / 6.5 #define SYSCTL_SYSDIV_7_5 0xC3800000 // Processor clock is pll / 7.5 #define SYSCTL_SYSDIV_8_5 0xC4000000 // Processor clock is pll / 8.5 #define SYSCTL_SYSDIV_9_5 0xC4800000 // Processor clock is pll / 9.5 #define SYSCTL_SYSDIV_10_5 0xC5000000 // Processor clock is pll / 10.5 #define SYSCTL_SYSDIV_11_5 0xC5800000 // Processor clock is pll / 11.5 #define SYSCTL_SYSDIV_12_5 0xC6000000 // Processor clock is pll / 12.5 #define SYSCTL_SYSDIV_13_5 0xC6800000 // Processor clock is pll / 13.5 #define SYSCTL_SYSDIV_14_5 0xC7000000 // Processor clock is pll / 14.5 #define SYSCTL_SYSDIV_15_5 0xC7800000 // Processor clock is pll / 15.5 #define SYSCTL_SYSDIV_16_5 0xC8000000 // Processor clock is pll / 16.5 #define SYSCTL_SYSDIV_17_5 0xC8800000 // Processor clock is pll / 17.5 #define SYSCTL_SYSDIV_18_5 0xC9000000 // Processor clock is pll / 18.5 #define SYSCTL_SYSDIV_19_5 0xC9800000 // Processor clock is pll / 19.5 #define SYSCTL_SYSDIV_20_5 0xCA000000 // Processor clock is pll / 20.5 #define SYSCTL_SYSDIV_21_5 0xCA800000 // Processor clock is pll / 21.5 #define SYSCTL_SYSDIV_22_5 0xCB000000 // Processor clock is pll / 22.5 #define SYSCTL_SYSDIV_23_5 0xCB800000 // Processor clock is pll / 23.5 #define SYSCTL_SYSDIV_24_5 0xCC000000 // Processor clock is pll / 24.5 #define SYSCTL_SYSDIV_25_5 0xCC800000 // Processor clock is pll / 25.5 #define SYSCTL_SYSDIV_26_5 0xCD000000 // Processor clock is pll / 26.5 #define SYSCTL_SYSDIV_27_5 0xCD800000 // Processor clock is pll / 27.5 #define SYSCTL_SYSDIV_28_5 0xCE000000 // Processor clock is pll / 28.5 #define SYSCTL_SYSDIV_29_5 0xCE800000 // Processor clock is pll / 29.5 #define SYSCTL_SYSDIV_30_5 0xCF000000 // Processor clock is pll / 30.5 #define SYSCTL_SYSDIV_31_5 0xCF800000 // Processor clock is pll / 31.5 #define SYSCTL_SYSDIV_32_5 0xD0000000 // Processor clock is pll / 32.5 #define SYSCTL_SYSDIV_33_5 0xD0800000 // Processor clock is pll / 33.5 #define SYSCTL_SYSDIV_34_5 0xD1000000 // Processor clock is pll / 34.5 #define SYSCTL_SYSDIV_35_5 0xD1800000 // Processor clock is pll / 35.5 #define SYSCTL_SYSDIV_36_5 0xD2000000 // Processor clock is pll / 36.5 #define SYSCTL_SYSDIV_37_5 0xD2800000 // Processor clock is pll / 37.5 #define SYSCTL_SYSDIV_38_5 0xD3000000 // Processor clock is pll / 38.5 #define SYSCTL_SYSDIV_39_5 0xD3800000 // Processor clock is pll / 39.5 #define SYSCTL_SYSDIV_40_5 0xD4000000 // Processor clock is pll / 40.5 #define SYSCTL_SYSDIV_41_5 0xD4800000 // Processor clock is pll / 41.5 #define SYSCTL_SYSDIV_42_5 0xD5000000 // Processor clock is pll / 42.5 #define SYSCTL_SYSDIV_43_5 0xD5800000 // Processor clock is pll / 43.5 #define SYSCTL_SYSDIV_44_5 0xD6000000 // Processor clock is pll / 44.5 #define SYSCTL_SYSDIV_45_5 0xD6800000 // Processor clock is pll / 45.5 #define SYSCTL_SYSDIV_46_5 0xD7000000 // Processor clock is pll / 46.5 #define SYSCTL_SYSDIV_47_5 0xD7800000 // Processor clock is pll / 47.5 #define SYSCTL_SYSDIV_48_5 0xD8000000 // Processor clock is pll / 48.5 #define SYSCTL_SYSDIV_49_5 0xD8800000 // Processor clock is pll / 49.5 #define SYSCTL_SYSDIV_50_5 0xD9000000 // Processor clock is pll / 50.5 #define SYSCTL_SYSDIV_51_5 0xD9800000 // Processor clock is pll / 51.5 #define SYSCTL_SYSDIV_52_5 0xDA000000 // Processor clock is pll / 52.5 #define SYSCTL_SYSDIV_53_5 0xDA800000 // Processor clock is pll / 53.5 #define SYSCTL_SYSDIV_54_5 0xDB000000 // Processor clock is pll / 54.5 #define SYSCTL_SYSDIV_55_5 0xDB800000 // Processor clock is pll / 55.5 #define SYSCTL_SYSDIV_56_5 0xDC000000 // Processor clock is pll / 56.5 #define SYSCTL_SYSDIV_57_5 0xDC800000 // Processor clock is pll / 57.5 #define SYSCTL_SYSDIV_58_5 0xDD000000 // Processor clock is pll / 58.5 #define SYSCTL_SYSDIV_59_5 0xDD800000 // Processor clock is pll / 59.5 #define SYSCTL_SYSDIV_60_5 0xDE000000 // Processor clock is pll / 60.5 #define SYSCTL_SYSDIV_61_5 0xDE800000 // Processor clock is pll / 61.5 #define SYSCTL_SYSDIV_62_5 0xDF000000 // Processor clock is pll / 62.5 #define SYSCTL_SYSDIV_63_5 0xDF800000 // Processor clock is pll / 63.5 #define SYSCTL_USE_PLL 0x00000000 // System clock is the PLL clock #define SYSCTL_USE_OSC 0x00003800 // System clock is the osc clock #define SYSCTL_XTAL_1MHZ 0x00000000 // External crystal is 1MHz #define SYSCTL_XTAL_1_84MHZ 0x00000040 // External crystal is 1.8432MHz #define SYSCTL_XTAL_2MHZ 0x00000080 // External crystal is 2MHz #define SYSCTL_XTAL_2_45MHZ 0x000000C0 // External crystal is 2.4576MHz #define SYSCTL_XTAL_3_57MHZ 0x00000100 // External crystal is 3.579545MHz #define SYSCTL_XTAL_3_68MHZ 0x00000140 // External crystal is 3.6864MHz #define SYSCTL_XTAL_4MHZ 0x00000180 // External crystal is 4MHz #define SYSCTL_XTAL_4_09MHZ 0x000001C0 // External crystal is 4.096MHz #define SYSCTL_XTAL_4_91MHZ 0x00000200 // External crystal is 4.9152MHz #define SYSCTL_XTAL_5MHZ 0x00000240 // External crystal is 5MHz #define SYSCTL_XTAL_5_12MHZ 0x00000280 // External crystal is 5.12MHz #define SYSCTL_XTAL_6MHZ 0x000002C0 // External crystal is 6MHz #define SYSCTL_XTAL_6_14MHZ 0x00000300 // External crystal is 6.144MHz #define SYSCTL_XTAL_7_37MHZ 0x00000340 // External crystal is 7.3728MHz #define SYSCTL_XTAL_8MHZ 0x00000380 // External crystal is 8MHz #define SYSCTL_XTAL_8_19MHZ 0x000003C0 // External crystal is 8.192MHz #define SYSCTL_XTAL_10MHZ 0x00000400 // External crystal is 10 MHz #define SYSCTL_XTAL_12MHZ 0x00000440 // External crystal is 12 MHz #define SYSCTL_XTAL_12_2MHZ 0x00000480 // External crystal is 12.288 MHz #define SYSCTL_XTAL_13_5MHZ 0x000004C0 // External crystal is 13.56 MHz #define SYSCTL_XTAL_14_3MHZ 0x00000500 // External crystal is 14.31818 MHz #define SYSCTL_XTAL_16MHZ 0x00000540 // External crystal is 16 MHz #define SYSCTL_XTAL_16_3MHZ 0x00000580 // External crystal is 16.384 MHz #define SYSCTL_XTAL_18MHZ 0x000005C0 // External crystal is 18.0 MHz #define SYSCTL_XTAL_20MHZ 0x00000600 // External crystal is 20.0 MHz #define SYSCTL_XTAL_24MHZ 0x00000640 // External crystal is 24.0 MHz #define SYSCTL_XTAL_25MHZ 0x00000680 // External crystal is 25.0 MHz #define SYSCTL_OSC_MAIN 0x00000000 // Osc source is main osc #define SYSCTL_OSC_INT 0x00000010 // Osc source is int. osc #define SYSCTL_OSC_INT4 0x00000020 // Osc source is int. osc /4 #define SYSCTL_OSC_INT30 0x00000030 // Osc source is int. 30 KHz #define SYSCTL_OSC_EXT4_19 0x80000028 // Osc source is ext. 4.19 MHz #define SYSCTL_OSC_EXT32 0x80000038 // Osc source is ext. 32 KHz #define SYSCTL_INT_OSC_DIS 0x00000002 // Disable internal oscillator #define SYSCTL_MAIN_OSC_DIS 0x00000001 // Disable main oscillator //============================================================================* // // The following are values that can be passed to the SysCtlDeepSleepClockSet() // API as the ulConfig parameter. // //============================================================================* #define SYSCTL_DSLP_DIV_1 0x00000000 // Deep-sleep clock is osc /1 #define SYSCTL_DSLP_DIV_2 0x00800000 // Deep-sleep clock is osc /2 #define SYSCTL_DSLP_DIV_3 0x01000000 // Deep-sleep clock is osc /3 #define SYSCTL_DSLP_DIV_4 0x01800000 // Deep-sleep clock is osc /4 #define SYSCTL_DSLP_DIV_5 0x02000000 // Deep-sleep clock is osc /5 #define SYSCTL_DSLP_DIV_6 0x02800000 // Deep-sleep clock is osc /6 #define SYSCTL_DSLP_DIV_7 0x03000000 // Deep-sleep clock is osc /7 #define SYSCTL_DSLP_DIV_8 0x03800000 // Deep-sleep clock is osc /8 #define SYSCTL_DSLP_DIV_9 0x04000000 // Deep-sleep clock is osc /9 #define SYSCTL_DSLP_DIV_10 0x04800000 // Deep-sleep clock is osc /10 #define SYSCTL_DSLP_DIV_11 0x05000000 // Deep-sleep clock is osc /11 #define SYSCTL_DSLP_DIV_12 0x05800000 // Deep-sleep clock is osc /12 #define SYSCTL_DSLP_DIV_13 0x06000000 // Deep-sleep clock is osc /13 #define SYSCTL_DSLP_DIV_14 0x06800000 // Deep-sleep clock is osc /14 #define SYSCTL_DSLP_DIV_15 0x07000000 // Deep-sleep clock is osc /15 #define SYSCTL_DSLP_DIV_16 0x07800000 // Deep-sleep clock is osc /16 #define SYSCTL_DSLP_DIV_17 0x08000000 // Deep-sleep clock is osc /17 #define SYSCTL_DSLP_DIV_18 0x08800000 // Deep-sleep clock is osc /18 #define SYSCTL_DSLP_DIV_19 0x09000000 // Deep-sleep clock is osc /19 #define SYSCTL_DSLP_DIV_20 0x09800000 // Deep-sleep clock is osc /20 #define SYSCTL_DSLP_DIV_21 0x0A000000 // Deep-sleep clock is osc /21 #define SYSCTL_DSLP_DIV_22 0x0A800000 // Deep-sleep clock is osc /22 #define SYSCTL_DSLP_DIV_23 0x0B000000 // Deep-sleep clock is osc /23 #define SYSCTL_DSLP_DIV_24 0x0B800000 // Deep-sleep clock is osc /24 #define SYSCTL_DSLP_DIV_25 0x0C000000 // Deep-sleep clock is osc /25 #define SYSCTL_DSLP_DIV_26 0x0C800000 // Deep-sleep clock is osc /26 #define SYSCTL_DSLP_DIV_27 0x0D000000 // Deep-sleep clock is osc /27 #define SYSCTL_DSLP_DIV_28 0x0D800000 // Deep-sleep clock is osc /28 #define SYSCTL_DSLP_DIV_29 0x0E000000 // Deep-sleep clock is osc /29 #define SYSCTL_DSLP_DIV_30 0x0E800000 // Deep-sleep clock is osc /30 #define SYSCTL_DSLP_DIV_31 0x0F000000 // Deep-sleep clock is osc /31 #define SYSCTL_DSLP_DIV_32 0x0F800000 // Deep-sleep clock is osc /32 #define SYSCTL_DSLP_DIV_33 0x10000000 // Deep-sleep clock is osc /33 #define SYSCTL_DSLP_DIV_34 0x10800000 // Deep-sleep clock is osc /34 #define SYSCTL_DSLP_DIV_35 0x11000000 // Deep-sleep clock is osc /35 #define SYSCTL_DSLP_DIV_36 0x11800000 // Deep-sleep clock is osc /36 #define SYSCTL_DSLP_DIV_37 0x12000000 // Deep-sleep clock is osc /37 #define SYSCTL_DSLP_DIV_38 0x12800000 // Deep-sleep clock is osc /38 #define SYSCTL_DSLP_DIV_39 0x13000000 // Deep-sleep clock is osc /39 #define SYSCTL_DSLP_DIV_40 0x13800000 // Deep-sleep clock is osc /40 #define SYSCTL_DSLP_DIV_41 0x14000000 // Deep-sleep clock is osc /41 #define SYSCTL_DSLP_DIV_42 0x14800000 // Deep-sleep clock is osc /42 #define SYSCTL_DSLP_DIV_43 0x15000000 // Deep-sleep clock is osc /43 #define SYSCTL_DSLP_DIV_44 0x15800000 // Deep-sleep clock is osc /44 #define SYSCTL_DSLP_DIV_45 0x16000000 // Deep-sleep clock is osc /45 #define SYSCTL_DSLP_DIV_46 0x16800000 // Deep-sleep clock is osc /46 #define SYSCTL_DSLP_DIV_47 0x17000000 // Deep-sleep clock is osc /47 #define SYSCTL_DSLP_DIV_48 0x17800000 // Deep-sleep clock is osc /48 #define SYSCTL_DSLP_DIV_49 0x18000000 // Deep-sleep clock is osc /49 #define SYSCTL_DSLP_DIV_50 0x18800000 // Deep-sleep clock is osc /50 #define SYSCTL_DSLP_DIV_51 0x19000000 // Deep-sleep clock is osc /51 #define SYSCTL_DSLP_DIV_52 0x19800000 // Deep-sleep clock is osc /52 #define SYSCTL_DSLP_DIV_53 0x1A000000 // Deep-sleep clock is osc /53 #define SYSCTL_DSLP_DIV_54 0x1A800000 // Deep-sleep clock is osc /54 #define SYSCTL_DSLP_DIV_55 0x1B000000 // Deep-sleep clock is osc /55 #define SYSCTL_DSLP_DIV_56 0x1B800000 // Deep-sleep clock is osc /56 #define SYSCTL_DSLP_DIV_57 0x1C000000 // Deep-sleep clock is osc /57 #define SYSCTL_DSLP_DIV_58 0x1C800000 // Deep-sleep clock is osc /58 #define SYSCTL_DSLP_DIV_59 0x1D000000 // Deep-sleep clock is osc /59 #define SYSCTL_DSLP_DIV_60 0x1D800000 // Deep-sleep clock is osc /60 #define SYSCTL_DSLP_DIV_61 0x1E000000 // Deep-sleep clock is osc /61 #define SYSCTL_DSLP_DIV_62 0x1E800000 // Deep-sleep clock is osc /62 #define SYSCTL_DSLP_DIV_63 0x1F000000 // Deep-sleep clock is osc /63 #define SYSCTL_DSLP_DIV_64 0x1F800000 // Deep-sleep clock is osc /64 #define SYSCTL_DSLP_OSC_MAIN 0x00000000 // Osc source is main osc #define SYSCTL_DSLP_OSC_INT 0x00000010 // Osc source is int. osc #define SYSCTL_DSLP_OSC_INT30 0x00000030 // Osc source is int. 30 KHz #define SYSCTL_DSLP_OSC_EXT32 0x00000070 // Osc source is ext. 32 KHz #define SYSCTL_DSLP_PIOSC_PD 0x00000002 // Power down PIOSC in deep-sleep //============================================================================* // // Prototypes for the APIs. // //============================================================================* extern unsigned long SysCtlSRAMSizeGet(void); extern unsigned long SysCtlFlashSizeGet(void); extern tBoolean SysCtlPinPresent(unsigned long ulPin); extern tBoolean SysCtlPeripheralPresent(unsigned long ulPeripheral); extern tBoolean SysCtlPeripheralReady(unsigned long ulPeripheral); extern void SysCtlPeripheralPowerOn(unsigned long ulPeripheral); extern void SysCtlPeripheralPowerOff(unsigned long ulPeripheral); extern void SysCtlPeripheralReset(unsigned long ulPeripheral); extern void SysCtlPeripheralEnable(unsigned long ulPeripheral); extern void SysCtlPeripheralDisable(unsigned long ulPeripheral); extern void SysCtlPeripheralSleepEnable(unsigned long ulPeripheral); extern void SysCtlPeripheralSleepDisable(unsigned long ulPeripheral); extern void SysCtlPeripheralDeepSleepEnable(unsigned long ulPeripheral); extern void SysCtlPeripheralDeepSleepDisable(unsigned long ulPeripheral); extern void SysCtlPeripheralClockGating(tBoolean bEnable); extern void SysCtlIntRegister(void (*pfnHandler)(void)); extern void SysCtlIntUnregister(void); extern void SysCtlIntEnable(unsigned long ulInts); extern void SysCtlIntDisable(unsigned long ulInts); extern void SysCtlIntClear(unsigned long ulInts); extern unsigned long SysCtlIntStatus(tBoolean bMasked); extern void SysCtlLDOSet(unsigned long ulVoltage); extern unsigned long SysCtlLDOGet(void); extern void SysCtlLDOConfigSet(unsigned long ulConfig); extern void SysCtlReset(void); extern void SysCtlSleep(void); extern void SysCtlDeepSleep(void); extern unsigned long SysCtlResetCauseGet(void); extern void SysCtlResetCauseClear(unsigned long ulCauses); extern void SysCtlBrownOutConfigSet(unsigned long ulConfig, unsigned long ulDelay); extern void SysCtlDelay(unsigned long ulCount); extern void SysCtlMOSCConfigSet(unsigned long ulConfig); extern unsigned long SysCtlPIOSCCalibrate(unsigned long ulType); extern void SysCtlClockSet(unsigned long ulConfig); extern unsigned long SysCtlClockGet(void); extern void SysCtlDeepSleepClockSet(unsigned long ulConfig); extern void SysCtlPWMClockSet(unsigned long ulConfig); extern unsigned long SysCtlPWMClockGet(void); extern void SysCtlADCSpeedSet(unsigned long ulSpeed); extern unsigned long SysCtlADCSpeedGet(void); extern void SysCtlIOSCVerificationSet(tBoolean bEnable); extern void SysCtlMOSCVerificationSet(tBoolean bEnable); extern void SysCtlPLLVerificationSet(tBoolean bEnable); extern void SysCtlClkVerificationClear(void); extern void SysCtlGPIOAHBEnable(unsigned long ulGPIOPeripheral); extern void SysCtlGPIOAHBDisable(unsigned long ulGPIOPeripheral); extern void SysCtlUSBPLLEnable(void); extern void SysCtlUSBPLLDisable(void); extern unsigned long SysCtlI2SMClkSet(unsigned long ulInputClock, unsigned long ulMClk); //============================================================================* // // Mark the end of the C bindings section for C++ compilers. // //============================================================================* #ifdef __cplusplus } #endif #endif // __SYSCTL_H__ ================================================ FILE: 3rd_party/ek-tm4c123gxl/system_TM4C123GH6PM.c ================================================ /**************************************************************************//** * @file system_TM4C123GH6PM.c * @brief CMSIS Device System Source File for * Texas Instruments TIVA TM4C123 Device Series * @version V1.00 * @date 27. March 2013 * * @note * modified by Keil ******************************************************************************/ #include #include "TM4C123GH6PM.h" /*---------------------------------------------------------------------------- DEFINES *----------------------------------------------------------------------------*/ //-------- <<< Use Configuration Wizard in Context Menu >>> ------------------ // // This file can be used by the Keil uVision configuration wizard to set // the following system clock configuration values. Or the value of the // macros can be directly edited below if not using the uVision configuration // wizard. // //--------------------- Clock Configuration ---------------------------------- // // Clock Configuration // Uncheck this box to skip the clock configuration. // // The following controls whether the system clock is configured in the // SystemInit() function. If it is defined to be 1 then the system clock // will be configured according to the macros in the rest of this file. // If it is defined to be 0, then the system clock configuration is bypassed. // #define CLOCK_SETUP 1 //********************************* RCC *************************************** // // Run-Mode Clock Configuration (RCC) // SYSDIV: System Clock Divisor <2-16> // Specifies the divisor used to generate the system clock from // either the PLL output of 200 MHz, or the chosen oscillator. // // The following value is the system clock divisor. This will be applied if // USESYSDIV (see below) is enabled. The valid range of dividers is 2-16. // #define CFG_RCC_SYSDIV 4 // USESYSDIV: Enable System Clock Divider // Check this box to use the System Clock Divider // // The following controls whether the system clock divider is used. If the // value is 1, then the system clock divider is used, and the value of the // system divider is defined by SYSDIV (see above). If the value is 0, then // the system clock divider is not used. // #define CFG_RCC_USESYSDIV 1 // USEPWMDIV: Enable PWM Clock Divider // Check this box to use the PWM Clock Divider // // The following controls whether the PWM clock divider is used. If the // value is 1, then the PWM clock divider is used, and the value of the // PWM divider is defined by PWMDIV (see below). If the value is 0, then // the PWM clock divider is not used. // #define CFG_RCC_USEPWMDIV 1 // PWMDIV: PWM Unit Clock Divisor // <0=> 0: SysClk / 2 // <1=> 1: SysClk / 4 // <2=> 2: SysClk / 8 // <3=> 3: SysClk / 16 // <4=> 4: SysClk / 32 // <5=> 5: SysClk / 64 // <6=> 6: SysClk / 64 // <7=> 7: SysClk / 64 (default) // Specifies the divisor used to generate the PWM time base, // from the System Clock // // The following value determines the PWM clock divider. It is used if // USEPWMDIV is enabled (see above). Otherwise the PWM clock is the same as // the system clock. The value of the divider is determined by the table // above. // #define CFG_RCC_PWMDIV 7 // PWRDN: PLL Power Down // Check this box to disable the PLL. You must also choose // PLL Bypass. // // If the following value is 1, then the PLL is powered down. Keep this value // as 1 if you do not need to use the PLL. In this case, BYPASS (see below) // must also be set to 1. If you are using the PLL, then this value must be // set to 0. // #define CFG_RCC_PWRDN 0 // BYPASS: PLL Bypass // Check this box to not use the PLL for the System Clock // // Set the following value to 1 to bypass the PLL and not use it for the // system clock. You must set this to 1 if PWRDN (above) is set to 1. Set // this to 0 if you are using the PLL. // #define CFG_RCC_BYPASS 0 // XTAL: Crystal Value // < 0=> 0: 1.0000 MHz (can not be used with PLL) // < 1=> 1: 1.8432 MHz (can not be used with PLL) // < 2=> 2: 2.0000 MHz (can not be used with PLL) // < 3=> 3: 2.4576 MHz (can not be used with PLL) // < 4=> 4: 3.579545 MHz // < 5=> 5: 3.6864 MHz // < 6=> 6: 4.0000 MHz // < 7=> 7: 4.096 MHz // < 8=> 8: 4.9152 MHz // < 9=> 9: 5.0000 MHz // <10=> 10: 5.12 MHz // <11=> 11: 6.0000 MHz (default) // <12=> 12: 6.144 MHz // <13=> 13: 7.3728 MHz // <14=> 14: 8.0000 MHz // <15=> 15: 8.192 MHz // <16=> 16: 10.0 MHz // <17=> 17: 12.0 MHz // <18=> 18: 12.288 MHz // <19=> 19: 13.56 MHz // <20=> 20: 14.31818 MHz // <21=> 21: 16.0 MHz // <22=> 22: 16.384 MHz // This is the crystal frequency used for the main oscillator // // This value defines the crystal frequency for the main oscillator, according // to the table in the comments above. If an external crystal is used, then // this value must be set to match the value of the crystal. // #define CFG_RCC_XTAL 21 // OSCSRC: Oscillator Source // <0=> 0: MOSC Main oscillator // <1=> 1: IOSC Internal oscillator (default) // <2=> 2: IOSC/4 Internal oscillator / 4 (this is necessary if used as input to PLL) // <3=> 3: 30kHz 30-KHz internal oscillator // Chooses the oscillator that is used for the system clock, // or the PLL input. // // The following value chooses the oscillator source according to the table in // the comments above. // #define CFG_RCC_OSCSRC 0 // IOSCDIS: Internal Oscillator Disable // Check this box to turn off the internal oscillator // // Set the following value to 1 to turn off the internal oscillator. This // value can be set to 1 if you are not using the internal oscillator. // #define CFG_RCC_IOSCDIS 1 // MOSCDIS: Main Oscillator Disable // Check this box to turn off the main oscillator // // Set the following value to 1 to turn off the main oscillator. This // value can be set to 1 if you are not using the main oscillator. // #define CFG_RCC_MOSCDIS 0 // //********************************* RCC2 ************************************** // // Run-Mode Clock Configuration 2 (RCC2) // USERCC2: Use RCC2 // Check this box to override some fields in RCC. RCC2 provides // more bits for the system clock divider, and provides an // additional oscillator source. If you do not need these // additional features, then leave this box unchecked. // // Set the following value to 1 to use the RCC2 register. The RCC2 register // overrides some of the fields in the RCC register if it is used. // #define CFG_RCC2_USERCC2 0 // SYSDIV2: System Clock Divisor <2-64> // Specifies the divisor used to generate the system clock from // either the PLL output of 200 MHz, or the oscillator. // // The following value is the system clock divisor. This will be applied if // USESYSDIV in RCC is enabled. The valid range of dividers is 2-64. // #define CFG_RCC_SYSDIV2 4 // PWRDN2: Power Down PLL // Check this box to disable the PLL. You must also choose // PLL Bypass. // // If the following value is 1, then the PLL is powered down. Keep this value // as 1 if you do not need to use the PLL. In this case, BYPASS2 (see below) // must also be set to 1. If you are using the PLL, then this value must be // set to 0. // #define CFG_RCC_PWRDN2 0 // BYPASS2: Bypass PLL // Check this box to not use the PLL for the System Clock // // Set the following value to 1 to bypass the PLL and not use it for the // system clock. You must set this to 1 if PWRDN2 (above) is set to 1. Set // this to 0 if you are using the PLL. // #define CFG_RCC_BYPASS2 0 // OSCSRC2: Oscillator Source // <0=> 0: MOSC Main oscillator // <1=> 1: IOSC Internal oscillator (default) // <2=> 2: IOSC/4 Internal oscillator / 4 (this is necessary if used as input to PLL) // <3=> 3: 30kHz 30-kHz internal oscillator // <7=> 7: 32kHz 32.768-kHz external oscillator // The oscillator that is used for the system clock, or the PLL input. // // The following value chooses the oscillator source according to the table in // the comments above. // #define CFG_RCC_OSCSRC2 0 // // // //-------- <<< end of configuration section >>> ------------------------------ // // The following macros are used to program the RCC and RCC2 registers in // the SystemInit() function. Edit the macros above to change these values. // #define RCC_Val \ ( \ ((CFG_RCC_SYSDIV - 1) << 23) | \ (CFG_RCC_USESYSDIV << 22) | \ (CFG_RCC_USEPWMDIV << 20) | \ (CFG_RCC_PWMDIV << 17) | \ (CFG_RCC_PWRDN << 13) | \ (CFG_RCC_BYPASS << 11) | \ (CFG_RCC_XTAL << 6) | \ (CFG_RCC_OSCSRC << 4) | \ (CFG_RCC_IOSCDIS << 1) | \ (CFG_RCC_MOSCDIS << 1)\ ) #define RCC2_Val \ ( \ (CFG_RCC2_USERCC2 << 31) | \ ((CFG_RCC_SYSDIV2 - 1) << 23) | \ (CFG_RCC_PWRDN2 << 13) | \ (CFG_RCC_BYPASS2 << 11) | \ (CFG_RCC_OSCSRC2 << 4)\ ) /*---------------------------------------------------------------------------- Define clocks *----------------------------------------------------------------------------*/ #define XTALM (16000000UL) /* Main oscillator freq */ #define XTALI (12000000UL) /* Internal oscillator freq */ #define XTAL30K ( 30000UL) /* Internal 30K oscillator freq */ #define XTAL32K ( 32768UL) /* external 32K oscillator freq */ #define PLL_CLK (400000000UL) #define ADC_CLK (PLL_CLK/25) #define CAN_CLK (PLL_CLK/50) /* Determine clock frequency according to clock register values */ #if (RCC2_Val & (1UL<<31)) /* is rcc2 used ? */ #if (RCC2_Val & (1UL<<11)) /* check BYPASS */ #if (((RCC2_Val>>4) & 0x07) == 0x0) #if (((RCC_Val>>6) & 0x1F) == 0x0) #define __CORE_CLK_PRE 1000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x1) #define __CORE_CLK_PRE 1843200UL #elif (((RCC_Val>>6) & 0x1F) == 0x2) #define __CORE_CLK_PRE 2000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x3) #define __CORE_CLK_PRE 2457600UL #elif (((RCC_Val>>6) & 0x1F) == 0x4) #define __CORE_CLK_PRE 3579545UL #elif (((RCC_Val>>6) & 0x1F) == 0x5) #define __CORE_CLK_PRE 3686400UL #elif (((RCC_Val>>6) & 0x1F) == 0x6) #define __CORE_CLK_PRE 4000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x7) #define __CORE_CLK_PRE 4096000UL #elif (((RCC_Val>>6) & 0x1F) == 0x8) #define __CORE_CLK_PRE 4915200UL #elif (((RCC_Val>>6) & 0x1F) == 0x9) #define __CORE_CLK_PRE 5000000UL #elif (((RCC_Val>>6) & 0x1F) == 0xA) #define __CORE_CLK_PRE 5120000UL #elif (((RCC_Val>>6) & 0x1F) == 0xB) #define __CORE_CLK_PRE 6000000UL #elif (((RCC_Val>>6) & 0x1F) == 0xC) #define __CORE_CLK_PRE 6144000UL #elif (((RCC_Val>>6) & 0x1F) == 0xD) #define __CORE_CLK_PRE 7372800UL #elif (((RCC_Val>>6) & 0x1F) == 0xE) #define __CORE_CLK_PRE 8000000UL #elif (((RCC_Val>>6) & 0x1F) == 0xF) #define __CORE_CLK_PRE 8192000UL #elif (((RCC_Val>>6) & 0x1F) == 0x10) #define __CORE_CLK_PRE 10000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x11) #define __CORE_CLK_PRE 12000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x12) #define __CORE_CLK_PRE 12288000UL #elif (((RCC_Val>>6) & 0x1F) == 0x13) #define __CORE_CLK_PRE 13560000UL #elif (((RCC_Val>>6) & 0x1F) == 0x14) #define __CORE_CLK_PRE 14318180UL #elif (((RCC_Val>>6) & 0x1F) == 0x15) #define __CORE_CLK_PRE 16000000UL #else #define __CORE_CLK_PRE 16384000UL #endif #elif (((RCC2_Val>>4) & 0x07) == 0x1) #define __CORE_CLK_PRE XTALI #elif (((RCC2_Val>>4) & 0x07) == 0x2) #define __CORE_CLK_PRE (XTALI/4) #else #define __CORE_CLK_PRE XTAL30K #endif #else #define __CORE_CLK_PRE PLL_CLK #endif #if (RCC_Val & (1UL<<22)) /* check USESYSDIV */ #if (RCC2_Val & (1UL<<11)) #define __CORE_CLK (__CORE_CLK_PRE / (((RCC2_Val>>23) & (0x3F)) + 1)) #else #define __CORE_CLK (__CORE_CLK_PRE / (((RCC2_Val>>23) & (0x3F)) + 1) / 2) #endif #else #define __CORE_CLK __CORE_CLK_PRE #endif #else #if (RCC_Val & (1UL<<11)) /* check BYPASS */ #if (((RCC_Val>>4) & 0x03) == 0x0) #if (((RCC_Val>>6) & 0x1F) == 0x0) #define __CORE_CLK_PRE 1000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x1) #define __CORE_CLK_PRE 1843200UL #elif (((RCC_Val>>6) & 0x1F) == 0x2) #define __CORE_CLK_PRE 2000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x3) #define __CORE_CLK_PRE 2457600UL #elif (((RCC_Val>>6) & 0x1F) == 0x4) #define __CORE_CLK_PRE 3579545UL #elif (((RCC_Val>>6) & 0x1F) == 0x5) #define __CORE_CLK_PRE 3686400UL #elif (((RCC_Val>>6) & 0x1F) == 0x6) #define __CORE_CLK_PRE 4000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x7) #define __CORE_CLK_PRE 4096000UL #elif (((RCC_Val>>6) & 0x1F) == 0x8) #define __CORE_CLK_PRE 4915200UL #elif (((RCC_Val>>6) & 0x1F) == 0x9) #define __CORE_CLK_PRE 5000000UL #elif (((RCC_Val>>6) & 0x1F) == 0xA) #define __CORE_CLK_PRE 5120000UL #elif (((RCC_Val>>6) & 0x1F) == 0xB) #define __CORE_CLK_PRE 6000000UL #elif (((RCC_Val>>6) & 0x1F) == 0xC) #define __CORE_CLK_PRE 6144000UL #elif (((RCC_Val>>6) & 0x1F) == 0xD) #define __CORE_CLK_PRE 7372800UL #elif (((RCC_Val>>6) & 0x1F) == 0xE) #define __CORE_CLK_PRE 8000000UL #elif (((RCC_Val>>6) & 0x1F) == 0xF) #define __CORE_CLK_PRE 8192000UL #elif (((RCC_Val>>6) & 0x1F) == 0x10) #define __CORE_CLK_PRE 10000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x11) #define __CORE_CLK_PRE 12000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x12) #define __CORE_CLK_PRE 12288000UL #elif (((RCC_Val>>6) & 0x1F) == 0x13) #define __CORE_CLK_PRE 13560000UL #elif (((RCC_Val>>6) & 0x1F) == 0x14) #define __CORE_CLK_PRE 14318180UL #elif (((RCC_Val>>6) & 0x1F) == 0x15) #define __CORE_CLK_PRE 16000000UL #else #define __CORE_CLK_PRE 16384000UL #endif #elif (((RCC_Val>>4) & 0x03) == 0x1) #define __CORE_CLK_PRE XTALI #elif (((RCC_Val>>4) & 0x03) == 0x2) #define __CORE_CLK_PRE (XTALI/4) #else #define __CORE_CLK_PRE XTAL30K #endif #else #define __CORE_CLK_PRE PLL_CLK #endif #if (RCC_Val & (1UL<<22)) /* check USESYSDIV */ #if (RCC_Val & (1UL<<11)) /* check BYPASS */ #define __CORE_CLK (__CORE_CLK_PRE / (((RCC_Val>>23) & (0x0F)) + 1)) #else #define __CORE_CLK (__CORE_CLK_PRE / (((RCC_Val>>23) & (0x0F)) + 1) / 2) #endif #else #define __CORE_CLK __CORE_CLK_PRE #endif #endif /*---------------------------------------------------------------------------- Clock Variable definitions *----------------------------------------------------------------------------*/ uint32_t SystemCoreClock = __CORE_CLK; /*!< System Clock Frequency (Core Clock)*/ /*---------------------------------------------------------------------------- Clock functions *----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- Get the OSC clock *----------------------------------------------------------------------------*/ static uint32_t getOscClk (uint32_t xtal, uint32_t oscSrc) { uint32_t oscClk = XTALI; switch (oscSrc) { /* switch OSCSRC */ case 0: /* MOSC Main oscillator */ switch (xtal) { /* switch XTAL */ case 0x0: oscClk = 1000000UL; break; case 0x1: oscClk = 1843200UL; break; case 0x2: oscClk = 2000000UL; break; case 0x3: oscClk = 2457600UL; break; case 0x4: oscClk = 3579545UL; break; case 0x5: oscClk = 3686400UL; break; case 0x6: oscClk = 4000000UL; break; case 0x7: oscClk = 4096000UL; break; case 0x8: oscClk = 4915200UL; break; case 0x9: oscClk = 5000000UL; break; case 0xA: oscClk = 5120000UL; break; case 0xB: oscClk = 6000000UL; break; case 0xC: oscClk = 6144000UL; break; case 0xD: oscClk = 7372800UL; break; case 0xE: oscClk = 8000000UL; break; case 0xF: oscClk = 8192000UL; break; case 0x10: oscClk = 10000000UL; break; case 0x11: oscClk = 12000000UL; break; case 0x12: oscClk = 12288000UL; break; case 0x13: oscClk = 13560000UL; break; case 0x14: oscClk = 14318180UL; break; case 0x15: oscClk = 16000000UL; break; case 0x16: oscClk = 16384000UL; break; } break; case 1: /* IOSC Internal oscillator */ oscClk = XTALI; break; case 2: /* IOSC/4 Internal oscillator/4 */ oscClk = XTALI/4; break; case 3: /* 30kHz internal oscillator */ oscClk = XTAL30K; break; } return oscClk; } void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */ { uint32_t rcc, rcc2; /* Determine clock frequency according to clock register values */ rcc = SYSCTL->RCC; rcc2 = SYSCTL->RCC2; //if (rcc2 & SYSCTL_RCC2_USERCC2) if (rcc2 & (1UL<<31)) { /* is rcc2 is used ? */ // if (rcc2 & SYSCTL_RCC2_BYPASS2) if (rcc2 & (1UL<<11)) { /* check BYPASS */ SystemCoreClock = getOscClk (((rcc>>6) & 0x0F),((rcc2>>4) & 0x07)); } else { SystemCoreClock = PLL_CLK; } if (rcc & (1UL<<22)) { /* check USESYSDIV */ if (rcc2 & (1UL<<11)) { SystemCoreClock = SystemCoreClock / (((rcc2>>23) & (0x3F)) + 1); } else { SystemCoreClock = SystemCoreClock / (((rcc2>>23) & (0x3F)) + 1) / 2; } } } else { // if (RCC_Val & (1UL<<11)) { /* check BYPASS */ if (rcc & (1UL<<11)) { /* check BYPASS */ /* Simulation does not work at this point */ SystemCoreClock = getOscClk (((rcc>>6) & 0x1F),((rcc>>4) & 0x03)); } else { SystemCoreClock = PLL_CLK; } // if (rcc & SYSCTL_RCC_USE_SYSDIV) if (rcc & (1UL<<22)) { /* check USESYSDIV */ // if (rcc2 & SYSCTL_RCC_BYPASS) if (rcc & (1UL<<11)) { /* check BYPASS */ /* Simulation does not work at this point */ // if (RCC_Val & (1UL<<11)) { /* check BYPASS */ SystemCoreClock = SystemCoreClock / (((rcc>>23) & (0x0F)) + 1); } else { SystemCoreClock = SystemCoreClock / (((rcc>>23) & (0x0F)) + 1) / 2; } } } } /** * Initialize the system * * @param none * @return none * * @brief Setup the microcontroller system. * Initialize the System. */ void SystemInit (void) { #if(CLOCK_SETUP) volatile uint32_t i; #endif /* FPU settings ------------------------------------------------------------*/ #if (__FPU_USED == 1) SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */ (3UL << 11*2) ); /* set CP11 Full Access */ #endif #if(CLOCK_SETUP) SYSCTL->RCC2 = 0x07802810; /* set default value */ SYSCTL->RCC = 0x078E3AD1; /* set default value */ SYSCTL->RCC = (RCC_Val | (1UL<<11) | (1UL<<13)) & ~(1UL<<22); /* set value with BYPASS, PWRDN set, USESYSDIV reset */ SYSCTL->RCC2 = (RCC2_Val | (1UL<<11) | (1UL<<13)); /* set value with BYPASS, PWRDN set */ for (i = 0; i < 1000; i++); /* wait a while */ SYSCTL->RCC = (RCC_Val | (1UL<<11)) & ~(1UL<<22); /* set value with BYPASS, USESYSDIV reset */ SYSCTL->RCC2 = (RCC2_Val | (1UL<<11)); /* set value with BYPASS */ for (i = 0; i < 1000; i++); /* wait a while */ SYSCTL->RCC = (RCC_Val | (1<<11)); /* set value with BYPASS */ if ( (((RCC_Val & (1UL<<13)) == 0) && ((RCC2_Val & (1UL<<31)) == 0)) || (((RCC2_Val & (1UL<<13)) == 0) && ((RCC2_Val & (1UL<<31)) != 0)) ) { while ((SYSCTL->RIS & (1UL<<6)) != (1UL<<6)); /* wait until PLL is locked */ } SYSCTL->RCC = (RCC_Val); /* set value */ SYSCTL->RCC2 = (RCC2_Val); /* set value */ for (i = 0; i < 10000; i++); /* wait a while */ #endif } ================================================ FILE: 3rd_party/ek-tm4c123gxl/system_TM4C123GH6PM.h ================================================ /**************************************************************************//** * @file system_TM4C123GH6PM.h * @brief CMSIS Cortex-M4 Device Peripheral Access Layer Header File for * TI Tiva TM4C123 Class Devices * @version V3.1 * @date 15. May 2013 * * @note * Copyright (C) 2010-2011 ARM Limited. All rights reserved. * * @par * ARM Limited (ARM) is supplying this software for use with Cortex-M * processor based microcontrollers. This file can be freely distributed * within development tools that are supporting such ARM based processors. * * @par * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. ******************************************************************************/ #ifndef SYSTEM_TM4C123_H #define SYSTEM_TM4C123_H #include #ifdef __cplusplus extern "C" { #endif extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ /** * Initialize the system * * @param none * @return none * * @brief Setup the microcontroller system. * Initialize the System and update the SystemCoreClock variable. */ extern void SystemInit (void); /** * Update SystemCoreClock variable * * @param none * @return none * * @brief Updates the SystemCoreClock with current core Clock * retrieved from cpu registers. */ extern void SystemCoreClockUpdate (void); #ifdef __cplusplus } #endif #endif /* SYSTEM_TM4C123_H */ ================================================ FILE: 3rd_party/nucleo-c031c6/README.txt ================================================ This directory contains embedded code for the STM32 NUCLEO-C031C6 board. This code is then used to build ET tests for this board. See also the examples/ directory, make_nucleo-l152re makefiles. ================================================ FILE: 3rd_party/nucleo-c031c6/arm/startup_stm32c031xx.s ================================================ ;/***************************************************************************/ ; * @file startup_stm32c031xx.s for ARM-KEIL ARM assembler ; * @brief CMSIS Cortex-M0+ Core Device Startup File for STM32C031xx ; * @version CMSIS 5.9.0 ; * @date 1 Feb 2023 ; * ; * Modified by Quantum Leaps: ; * - Added relocating of the Vector Table to free up the 256B region at 0x0 ; * for NULL-pointer protection by the MPU. ; * - Modified all exception handlers to branch to assert_failed() ; * instead of locking up the CPU inside an endless loop. ; * ; * @description ; * Created from the CMSIS template for the specified device ; * Quantum Leaps, www.state-machine.com ; * ; * @note ; * The symbols Stack_Size and Heap_Size should be provided on the command- ; * line options to the assembler, for example as: ; * --pd "Stack_Size SETA 1024" --pd "Heap_Size SETA 0" ;****************************************************************************** ; Allocate space for the stack. ; AREA STACK, NOINIT, READWRITE, ALIGN=3 __stack_base StackMem SPACE Stack_Size ; provided in command-line option, for example: ; --pd "Stack_Size SETA 512" __stack_limit __initial_sp ;****************************************************************************** ; Allocate space for the heap. ; AREA HEAP, NOINIT, READWRITE, ALIGN=3 __heap_base HeapMem SPACE Heap_Size ; provided in command-line option, for example: ; --pd "Heap_Size SETA 0" __heap_limit ; Indicate that the code in this file preserves 8-byte alignment of the stack. PRESERVE8 ;****************************************************************************** ; The vector table. ; ; Place code into the reset code section. AREA RESET, DATA, READONLY, ALIGN=8 EXPORT __Vectors EXPORT __Vectors_End EXPORT __Vectors_Size __Vectors ; Initial Vector Table before relocation DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD SVC_Handler ; SVCall handler DCD DebugMon_Handler ; Debug Monitor handler DCD Default_Handler ; Reserved DCD PendSV_Handler ; PendSV handler DCD SysTick_Handler ; SysTick handler ; IRQ handlers... DCD WWDG_IRQHandler ; [ 0] Window Watchdog DCD Reserved1_IRQHandler ; [ 1] Reserved DCD RTC_IRQHandler ; [ 2] RTC through EXTI Line DCD FLASH_IRQHandler ; [ 3] FLASH DCD RCC_IRQHandler ; [ 4] RCC DCD EXTI0_1_IRQHandler ; [ 5] EXTI Line 0 and 1 DCD EXTI2_3_IRQHandler ; [ 6] EXTI Line 2 and 3 DCD EXTI4_15_IRQHandler ; [ 7] EXTI Line 4 to 15 DCD Reserved8_IRQHandler ; [ 8] Reserved DCD DMA1_Channel1_IRQHandler ; [ 9] DMA1 Channel 1 DCD DMA1_Channel2_3_IRQHandler ; [10] DMA1 Channel 2 and Channel 3 DCD DMAMUX1_IRQHandler ; [11] DMAMUX DCD ADC1_IRQHandler ; [12] ADC1 DCD TIM1_BRK_UP_TRG_COM_IRQHandler ; [13] TIM1 Break, Update, Trigger and Commutation DCD TIM1_CC_IRQHandler ; [14] TIM1 Capture Compare DCD Reserved15_IRQHandler ; [15] Reserved DCD TIM3_IRQHandler ; [16] TIM3 DCD Reserved17_IRQHandler ; [17] Reserved DCD Reserved18_IRQHandler ; [18] Reserved DCD TIM14_IRQHandler ; [19] TIM14 DCD Reserved20_IRQHandler ; [20] Reserved DCD TIM16_IRQHandler ; [21] TIM16 DCD TIM17_IRQHandler ; [22] TIM17 DCD I2C1_IRQHandler ; [23] I2C1 DCD Reserved24_IRQHandler ; [24] Reserved DCD SPI1_IRQHandler ; [25] SPI1 DCD Reserved26_IRQHandler ; [26] Reserved DCD USART1_IRQHandler ; [27] USART1 DCD USART2_IRQHandler ; [28] USART2 DCD Reserved29_IRQHandler ; [29] Reserved DCD Reserved30_IRQHandler ; [30] Reserved DCD Reserved31_IRQHandler ; [31] Reserved __Vectors_End __Vectors_Size EQU __Vectors_End - __Vectors ;****************************************************************************** ; This is the code for exception handlers. ; AREA |.text|, CODE, READONLY ;****************************************************************************** ; This is the code that gets called when the processor first starts execution ; following a reset event. ; Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main IMPORT assert_failed LDR r0,=SystemInit ; CMSIS system initialization BLX r0 ; Call the C library enty point that handles startup. This will copy ; the .data section initializers from flash to SRAM and zero fill the ; .bss section. ; NOTE: The __main function clears the C stack as well LDR r0,=__main BX r0 ; __main calls the main() function, which should not return, ; but just in case jump to assert_failed() if main returns. LDR r0,=str_EXIT MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_EXIT DCB "EXIT" ALIGN ENDP ;****************************************************************************** NMI_Handler PROC EXPORT NMI_Handler [WEAK] IMPORT assert_failed LDR r0,=str_NMI MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_NMI DCB "NMI" ALIGN ENDP ;****************************************************************************** HardFault_Handler PROC EXPORT HardFault_Handler [WEAK] IMPORT assert_failed LDR r0,=str_HardFault MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_HardFault DCB "HardFault" ALIGN ENDP ;****************************************************************************** ; ; Weak non-fault handlers... ; ;****************************************************************************** SVC_Handler PROC EXPORT SVC_Handler [WEAK] IMPORT assert_failed LDR r0,=str_SVC MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_SVC DCB "SVC" ALIGN ENDP ;****************************************************************************** DebugMon_Handler PROC EXPORT DebugMon_Handler [WEAK] IMPORT assert_failed LDR r0,=str_DebugMon MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_DebugMon DCB "DebugMon" ALIGN ENDP ;****************************************************************************** PendSV_Handler PROC EXPORT PendSV_Handler [WEAK] IMPORT assert_failed LDR r0,=str_PendSV MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_PendSV DCB "PendSV" ALIGN ENDP ;****************************************************************************** SysTick_Handler PROC EXPORT SysTick_Handler [WEAK] IMPORT assert_failed LDR r0,=str_SysTick MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_SysTick DCB "SysTick" ALIGN ENDP ;****************************************************************************** Default_Handler PROC EXPORT WWDG_IRQHandler [WEAK] EXPORT RTC_IRQHandler [WEAK] EXPORT FLASH_IRQHandler [WEAK] EXPORT RCC_IRQHandler [WEAK] EXPORT EXTI0_1_IRQHandler [WEAK] EXPORT EXTI2_3_IRQHandler [WEAK] EXPORT EXTI4_15_IRQHandler [WEAK] EXPORT DMA1_Channel1_IRQHandler [WEAK] EXPORT DMA1_Channel2_3_IRQHandler [WEAK] EXPORT DMAMUX1_IRQHandler [WEAK] EXPORT ADC1_IRQHandler [WEAK] EXPORT TIM1_BRK_UP_TRG_COM_IRQHandler [WEAK] EXPORT TIM1_CC_IRQHandler [WEAK] EXPORT TIM3_IRQHandler [WEAK] EXPORT TIM14_IRQHandler [WEAK] EXPORT TIM16_IRQHandler [WEAK] EXPORT TIM17_IRQHandler [WEAK] EXPORT I2C1_IRQHandler [WEAK] EXPORT SPI1_IRQHandler [WEAK] EXPORT USART1_IRQHandler [WEAK] EXPORT USART2_IRQHandler [WEAK] EXPORT Reserved1_IRQHandler [WEAK] EXPORT Reserved8_IRQHandler [WEAK] EXPORT Reserved15_IRQHandler [WEAK] EXPORT Reserved17_IRQHandler [WEAK] EXPORT Reserved18_IRQHandler [WEAK] EXPORT Reserved20_IRQHandler [WEAK] EXPORT Reserved24_IRQHandler [WEAK] EXPORT Reserved26_IRQHandler [WEAK] EXPORT Reserved29_IRQHandler [WEAK] EXPORT Reserved30_IRQHandler [WEAK] EXPORT Reserved31_IRQHandler [WEAK] WWDG_IRQHandler RTC_IRQHandler FLASH_IRQHandler RCC_IRQHandler EXTI0_1_IRQHandler EXTI2_3_IRQHandler EXTI4_15_IRQHandler DMA1_Channel1_IRQHandler DMA1_Channel2_3_IRQHandler DMAMUX1_IRQHandler ADC1_IRQHandler TIM1_BRK_UP_TRG_COM_IRQHandler TIM1_CC_IRQHandler TIM3_IRQHandler TIM14_IRQHandler TIM16_IRQHandler TIM17_IRQHandler I2C1_IRQHandler SPI1_IRQHandler USART1_IRQHandler USART2_IRQHandler Reserved1_IRQHandler Reserved8_IRQHandler Reserved15_IRQHandler Reserved17_IRQHandler Reserved18_IRQHandler Reserved20_IRQHandler Reserved24_IRQHandler Reserved26_IRQHandler Reserved29_IRQHandler Reserved30_IRQHandler Reserved31_IRQHandler LDR r0,=str_Undefined MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_Undefined DCB "Undefined" ALIGN ENDP ALIGN ; make sure the end of this section is aligned ;****************************************************************************** ; The function expected of the C library startup code for defining the stack ; and heap memory locations. For the C library version of the startup code, ; provide this function so that the C library initialization code can find out ; the location of the stack and heap. ; IF :DEF: __MICROLIB EXPORT __initial_sp EXPORT __stack_limit EXPORT __heap_base EXPORT __heap_limit ELSE IMPORT __use_two_region_memory EXPORT __user_initial_stackheap __user_initial_stackheap PROC LDR R0, =__heap_base LDR R1, =__stack_limit LDR R2, =__heap_limit LDR R3, =__stack_base BX LR ENDP ENDIF ALIGN ; make sure the end of this section is aligned END ; end of module ================================================ FILE: 3rd_party/nucleo-c031c6/gnu/nucleo-c031c6.ld ================================================ /***************************************************************************** * Linker script for for STM32C031C6, GNU-ARM linker * * Q u a n t u m L e a P s * ------------------------ * Modern Embedded Software * * Copyright (C) 2005 Quantum Leaps, LLC . * * SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial * * This software is dual-licensed under the terms of the open source GNU * General Public License version 3 (or any later version), or alternatively, * under the terms of one of the closed source Quantum Leaps commercial * licenses. * * The terms of the open source GNU General Public License version 3 * can be found at: * * The terms of the closed source Quantum Leaps commercial licenses * can be found at: * * Redistributions in source code must retain this top-level comment block. * Plagiarizing this software to sidestep the license obligations is illegal. * * Contact information: * * *****************************************************************************/ OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(Reset_Handler) /* entry Point */ MEMORY { /* memory map of STM32C031C6 */ ROM (rx) : ORIGIN = 0x08000000, LENGTH = 32K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 12K } /* The size of the stack used by the application. NOTE: you need to adjust */ STACK_SIZE = 2048; /* The size of the heap used by the application. NOTE: you need to adjust */ HEAP_SIZE = 0; SECTIONS { .isr_vector : { /* the vector table goes FIRST into ROM */ KEEP(*(.isr_vector)) /* vector table */ . = ALIGN(4); } >ROM .text : { /* code and constants */ . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); } >ROM .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >ROM .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >ROM .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(.fini_array*)) KEEP (*(SORT(.fini_array.*))) PROVIDE_HIDDEN (__fini_array_end = .); } >ROM _etext = .; /* global symbols at end of code */ .stack : { __stack_start__ = .; . = . + STACK_SIZE; . = ALIGN(4); __stack_end__ = .; } >RAM .data : AT (_etext) { __data_load = LOADADDR (.data); __data_start = .; *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); __data_end__ = .; _edata = __data_end__; } >RAM .bss : { __bss_start__ = .; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = .; } >RAM __exidx_start = .; .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM __exidx_end = .; PROVIDE ( end = _ebss ); PROVIDE ( _end = _ebss ); PROVIDE ( __end__ = _ebss ); .heap : { __heap_start__ = .; . = . + HEAP_SIZE; . = ALIGN(4); __heap_end__ = .; } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } } ================================================ FILE: 3rd_party/nucleo-c031c6/gnu/startup_stm32c031xx.c ================================================ /* File: startup_stm32c031xx.c for GNU-ARM * Purpose: startup file for STM32C031xx Cortex-M0+ device. * Should be used with GCC 'GNU Tools ARM Embedded' * Version: CMSIS 5.0.1 * Date: 2017-09-13 * * Modified by Quantum Leaps: * - Added relocating of the Vector Table to free up the 256B region at 0x0 * for NULL-pointer protection by the MPU. * - Modified all exception handlers to branch to assert_failed() * instead of locking up the CPU inside an endless loop. * * Created from the CMSIS template for the specified device * Quantum Leaps, www.state-machine.com * * NOTE: * The function assert_failed defined at the end of this file defines * the error/assertion handling policy for the application and might * need to be customized for each project. This function is defined in * assembly to re-set the stack pointer, in case it is corrupted by the * time assert_failed is called. */ /* start and end of stack defined in the linker script ---------------------*/ /*extern int __stack_start__;*/ extern int __stack_end__; /* Weak prototypes for error handlers --------------------------------------*/ /** * \note * The function assert_failed defined at the end of this file defines * the error/assertion handling policy for the application and might * need to be customized for each project. This function is defined in * assembly to avoid accessing the stack, which might be corrupted by * the time assert_failed is called. */ __attribute__ ((naked, noreturn)) void assert_failed(char const *module, int loc); /* Function prototypes -----------------------------------------------------*/ void Default_Handler(void); /* Default empty handler */ void Reset_Handler(void); /* Reset Handler */ void SystemInit(void); /* CMSIS system initialization */ /*---------------------------------------------------------------------------- * weak aliases for each Exception handler to the Default_Handler. * Any function with the same name will override these definitions. */ /* Cortex-M Processor fault exceptions... */ void NMI_Handler (void) __attribute__ ((weak)); void HardFault_Handler (void) __attribute__ ((weak)); void MemManage_Handler (void) __attribute__ ((weak)); void BusFault_Handler (void) __attribute__ ((weak)); void UsageFault_Handler (void) __attribute__ ((weak)); /* Cortex-M Processor non-fault exceptions... */ void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); void DebugMon_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); /* external interrupts... */ void WWDG_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void RTC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void FLASH_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void RCC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void EXTI0_1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void EXTI2_3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void EXTI4_15_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved8_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void DMA1_Channel1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA1_Channel2_3_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMAMUX1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void ADC1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void TIM1_BRK_UP_TRG_COM_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM1_CC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved15_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void TIM3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved17_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved18_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void TIM14_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved20_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void TIM16_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void TIM17_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void I2C1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved24_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void SPI1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved26_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void USART1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void USART2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved29_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved30_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved31_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); /*..........................................................................*/ __attribute__ ((section(".isr_vector"))) int const g_pfnVectors[] = { (int)&__stack_end__, /* Top of Stack */ (int)&Reset_Handler, /* Reset Handler */ (int)&NMI_Handler, /* NMI Handler */ (int)&HardFault_Handler, /* Hard Fault Handler */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&SVC_Handler, /* SVCall handler */ (int)&DebugMon_Handler, /* Debug monitor handler */ (int)&Default_Handler, /* Reserved */ (int)&PendSV_Handler, /* The PendSV handler */ (int)&SysTick_Handler, /* The SysTick handler */ /*IRQ handlers... */ (int)&WWDG_IRQHandler, /* [ 0] Window Watchdog */ (int)&Reserved1_IRQHandler, /* [ 1] Reserved */ (int)&RTC_IRQHandler, /* [ 2] RTC through EXTI Line */ (int)&FLASH_IRQHandler, /* [ 3] FLASH */ (int)&RCC_IRQHandler, /* [ 4] RCC */ (int)&EXTI0_1_IRQHandler, /* [ 5] EXTI Line 0 and 1 */ (int)&EXTI2_3_IRQHandler, /* [ 6] EXTI Line 2 and 3 */ (int)&EXTI4_15_IRQHandler, /* [ 7] EXTI Line 4 to 15 */ (int)&Reserved8_IRQHandler, /* [ 8] Reserved */ (int)&DMA1_Channel1_IRQHandler,/* [ 9] DMA1 Channel 1 */ (int)&DMA1_Channel2_3_IRQHandler,/* [10] DMA1 Channel 2 and Channel 3 */ (int)&DMAMUX1_IRQHandler, /* [11] DMAMUX */ (int)&ADC1_IRQHandler, /* [12] ADC1 */ (int)&TIM1_BRK_UP_TRG_COM_IRQHandler,/* [13] TIM1 Break,Update,Trigger & Comm */ (int)&TIM1_CC_IRQHandler, /* [14] TIM1 Capture Compare */ (int)&Reserved15_IRQHandler, /* [15] Reserved */ (int)&TIM3_IRQHandler, /* [16] TIM3 */ (int)&Reserved17_IRQHandler, /* [17] Reserved */ (int)&Reserved18_IRQHandler, /* [18] Reserved */ (int)&TIM14_IRQHandler, /* [19] TIM14 */ (int)&Reserved20_IRQHandler, /* [20] Reserved */ (int)&TIM16_IRQHandler, /* [21] TIM16 */ (int)&TIM17_IRQHandler, /* [22] TIM17 */ (int)&I2C1_IRQHandler, /* [23] I2C1 */ (int)&Reserved24_IRQHandler, /* [24] Reserved */ (int)&SPI1_IRQHandler, /* [25] SPI1 */ (int)&Reserved26_IRQHandler, /* [26] Reserved */ (int)&USART1_IRQHandler, /* [27] USART1 */ (int)&USART2_IRQHandler, /* [28] USART2 */ (int)&Reserved29_IRQHandler, /* [29] Reserved */ (int)&Reserved30_IRQHandler, /* [30] Reserved */ (int)&Reserved31_IRQHandler, /* [31] Reserved */ }; /* reset handler -----------------------------------------------------------*/ __attribute__((naked)) void Reset_Handler(void); void Reset_Handler(void) { extern int main(void); extern int __libc_init_array(void); extern unsigned __data_start; /* start of .data in the linker script */ extern unsigned __data_end__; /* end of .data in the linker script */ extern unsigned const __data_load; /* initialization values for .data */ extern unsigned __bss_start__; /* start of .bss in the linker script */ extern unsigned __bss_end__; /* end of .bss in the linker script */ extern void software_init_hook(void) __attribute__((weak)); SystemInit(); /* CMSIS system initialization */ /* copy the data segment initializers from flash to RAM... */ unsigned const *src = &__data_load; unsigned *dst; for (dst = &__data_start; dst < &__data_end__; ++dst, ++src) { *dst = *src; } /* zero fill the .bss segment in RAM... */ for (dst = &__bss_start__; dst < &__bss_end__; ++dst) { *dst = 0; } /* init hook provided? */ if (&software_init_hook != (void (*)(void))(0)) { /* give control to the RTOS */ software_init_hook(); /* this will also call __libc_init_array */ } else { /* call all static constructors in C++ (harmless in C programs) */ __libc_init_array(); (void)main(); /* application's entry point; should never return! */ } /* the previous code should not return, but assert just in case... */ assert_failed("Reset_Handler", 1U); } /* fault exception handlers ------------------------------------------------*/ __attribute__((naked)) void NMI_Handler(void); void NMI_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("NMI_Handler", 1U); } /*..........................................................................*/ __attribute__((naked)) void HardFault_Handler(void); void HardFault_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("HardFault_Handler", 1U); } /*..........................................................................*/ __attribute__((naked)) void Default_Handler(void); void Default_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("Default_Handler", 1U); } ================================================ FILE: 3rd_party/nucleo-c031c6/iar/startup_stm32c031xx.s ================================================ ;/***************************************************************************/ ; * @file startup_stm32c031xx.s for IAR ARM assembler ; * @brief CMSIS Cortex-M0+ Core Device Startup File for STM32C031xx ; * @version CMSIS 5.9.0 ; * @date 1 Feb 2023 ; * ; * Modified by Quantum Leaps: ; * - Added relocating of the Vector Table to free up the 256B region at 0x0 ; * for NULL-pointer protection by the MPU. ; * - Modified all exception handlers to branch to assert_failed() ; * instead of locking up the CPU inside an endless loop. ; * ; * @description ; * Created from the CMSIS template for the specified device ; * Quantum Leaps, www.state-machine.com ; * MODULE ?cstartup ; Forward declaration of sections. SECTION CSTACK:DATA:NOROOT(3) SECTION .intvec:CODE:NOROOT(8) PUBLIC __vector_table PUBLIC __Vectors PUBLIC __Vectors_End PUBLIC __Vectors_Size ;****************************************************************************** ; The vector table. ; DATA __vector_table ; Initial Vector Table before relocation DCD sfe(CSTACK) DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD SVC_Handler ; SVCall handler DCD DebugMon_Handler ; Debug Monitor handler DCD Default_Handler ; Reserved DCD PendSV_Handler ; PendSV handler DCD SysTick_Handler ; SysTick handler ; IRQ handlers... DCD WWDG_IRQHandler ; [ 0] Window Watchdog DCD Reserved1_IRQHandler ; [ 1] Reserved DCD RTC_IRQHandler ; [ 2] RTC through EXTI Line DCD FLASH_IRQHandler ; [ 3] FLASH DCD RCC_IRQHandler ; [ 4] RCC DCD EXTI0_1_IRQHandler ; [ 5] EXTI Line 0 and 1 DCD EXTI2_3_IRQHandler ; [ 6] EXTI Line 2 and 3 DCD EXTI4_15_IRQHandler ; [ 7] EXTI Line 4 to 15 DCD Reserved8_IRQHandler ; [ 8] Reserved DCD DMA1_Channel1_IRQHandler ; [ 9] DMA1 Channel 1 DCD DMA1_Channel2_3_IRQHandler ; [10] DMA1 Channel 2 and Channel 3 DCD DMAMUX1_IRQHandler ; [11] DMAMUX DCD ADC1_IRQHandler ; [12] ADC1 DCD TIM1_BRK_UP_TRG_COM_IRQHandler ; [13] TIM1 Break, Update, Trigger and Commutation DCD TIM1_CC_IRQHandler ; [14] TIM1 Capture Compare DCD Reserved15_IRQHandler ; [15] Reserved DCD TIM3_IRQHandler ; [16] TIM3 DCD Reserved17_IRQHandler ; [17] Reserved DCD Reserved18_IRQHandler ; [18] Reserved DCD TIM14_IRQHandler ; [19] TIM14 DCD Reserved20_IRQHandler ; [20] Reserved DCD TIM16_IRQHandler ; [21] TIM16 DCD TIM17_IRQHandler ; [22] TIM17 DCD I2C1_IRQHandler ; [23] I2C1 DCD Reserved24_IRQHandler ; [24] Reserved DCD SPI1_IRQHandler ; [25] SPI1 DCD Reserved26_IRQHandler ; [26] Reserved DCD USART1_IRQHandler ; [27] USART1 DCD USART2_IRQHandler ; [28] USART2 DCD Reserved29_IRQHandler ; [29] Reserved DCD Reserved30_IRQHandler ; [30] Reserved DCD Reserved31_IRQHandler ; [31] Reserved __Vectors_End __Vectors EQU __vector_table __Vectors_Size EQU __Vectors_End - __Vectors ;****************************************************************************** ; This is the code for exception handlers. ; SECTION .text:CODE:REORDER:NOROOT(2) ;****************************************************************************** ; This is the code that gets called when theessor first starts execution ; following a reset event. ; PUBWEAK Reset_Handler EXTERN SystemInit EXTERN __iar_program_start EXTERN assert_failed Reset_Handler LDR r0,=SystemInit ; CMSIS system initialization BLX r0 ; pre-fill the CSTACK with 0xDEADBEEF................... LDR r0,=0xDEADBEEF MOV r1,r0 LDR r2,=sfb(CSTACK) LDR r3,=sfe(CSTACK) Reset_stackInit_fill: STMIA r2!,{r0,r1} CMP r2,r3 BLT.N Reset_stackInit_fill LDR r0,=__iar_program_start ; IAR startup code BLX r0 ; __iar_program_start calls the main() function, which should not return, ; but just in case jump to assert_failed() if main returns. LDR r0,=str_EXIT MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_EXIT DCB "EXIT" ALIGNROM 2 ;****************************************************************************** PUBWEAK NMI_Handler NMI_Handler LDR r0,=str_NMI MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_NMI DCB "NMI" ALIGNROM 2 ;****************************************************************************** PUBWEAK HardFault_Handler HardFault_Handler LDR r0,=str_HardFault MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_HardFault DCB "HardFault" ALIGNROM 2 ;****************************************************************************** ; ; Weak non-fault handlers... ; ;****************************************************************************** PUBWEAK SVC_Handler SVC_Handler LDR r0,=str_SVC MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_SVC DCB "SVC" ALIGNROM 2 ;****************************************************************************** PUBWEAK DebugMon_Handler DebugMon_Handler LDR r0,=str_DebugMon MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_DebugMon DCB "DebugMon" ALIGNROM 2 ;****************************************************************************** PUBWEAK PendSV_Handler PendSV_Handler LDR r0,=str_PendSV MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_PendSV DCB "PendSV" ALIGNROM 2 ;****************************************************************************** PUBWEAK SysTick_Handler SysTick_Handler LDR r0,=str_SysTick MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_SysTick DCB "SysTick" ALIGNROM 2 ;****************************************************************************** ; Weak IRQ handlers... ; PUBWEAK Default_Handler PUBWEAK WWDG_IRQHandler PUBWEAK RTC_IRQHandler PUBWEAK FLASH_IRQHandler PUBWEAK RCC_IRQHandler PUBWEAK EXTI0_1_IRQHandler PUBWEAK EXTI2_3_IRQHandler PUBWEAK EXTI4_15_IRQHandler PUBWEAK DMA1_Channel1_IRQHandler PUBWEAK DMA1_Channel2_3_IRQHandler PUBWEAK DMAMUX1_IRQHandler PUBWEAK ADC1_IRQHandler PUBWEAK TIM1_BRK_UP_TRG_COM_IRQHandler PUBWEAK TIM1_CC_IRQHandler PUBWEAK TIM3_IRQHandler PUBWEAK TIM14_IRQHandler PUBWEAK TIM16_IRQHandler PUBWEAK TIM17_IRQHandler PUBWEAK I2C1_IRQHandler PUBWEAK SPI1_IRQHandler PUBWEAK USART1_IRQHandler PUBWEAK USART2_IRQHandler PUBWEAK Reserved1_IRQHandler PUBWEAK Reserved8_IRQHandler PUBWEAK Reserved15_IRQHandler PUBWEAK Reserved17_IRQHandler PUBWEAK Reserved18_IRQHandler PUBWEAK Reserved20_IRQHandler PUBWEAK Reserved24_IRQHandler PUBWEAK Reserved26_IRQHandler PUBWEAK Reserved29_IRQHandler PUBWEAK Reserved30_IRQHandler PUBWEAK Reserved31_IRQHandler Default_Handler WWDG_IRQHandler RTC_IRQHandler FLASH_IRQHandler RCC_IRQHandler EXTI0_1_IRQHandler EXTI2_3_IRQHandler EXTI4_15_IRQHandler DMA1_Channel1_IRQHandler DMA1_Channel2_3_IRQHandler DMAMUX1_IRQHandler ADC1_IRQHandler TIM1_BRK_UP_TRG_COM_IRQHandler TIM1_CC_IRQHandler TIM3_IRQHandler TIM14_IRQHandler TIM16_IRQHandler TIM17_IRQHandler I2C1_IRQHandler SPI1_IRQHandler USART1_IRQHandler USART2_IRQHandler Reserved1_IRQHandler Reserved8_IRQHandler Reserved15_IRQHandler Reserved17_IRQHandler Reserved18_IRQHandler Reserved20_IRQHandler Reserved24_IRQHandler Reserved26_IRQHandler Reserved29_IRQHandler Reserved30_IRQHandler Reserved31_IRQHandler LDR r0,=str_Undefined MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_Undefined DCB "Undefined" ALIGNROM 2 END ; end of module ================================================ FILE: 3rd_party/nucleo-c031c6/stm32c031xx.h ================================================ /** ****************************************************************************** * @file stm32c031xx.h * @author MCD Application Team * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer Header File. * This file contains all the peripheral register's definitions, bits * definitions and memory mapping for stm32c031xx devices. * * This file contains: * - Data structures and the address mapping for all peripherals * - Peripheral's registers declarations and bits definition * - Macros to access peripheral's registers hardware * ****************************************************************************** * @attention * * Copyright (c) 2022 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /** @addtogroup CMSIS_Device * @{ */ /** @addtogroup stm32c031xx * @{ */ #ifndef STM32C031xx_H #define STM32C031xx_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** @addtogroup Configuration_section_for_CMSIS * @{ */ /** * @brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ #define __CM0PLUS_REV 0 /*!< Core Revision r0p0 */ #define __MPU_PRESENT 1 /*!< STM32C0xx provides an MPU */ #define __VTOR_PRESENT 1 /*!< Vector Table Register supported */ #define __NVIC_PRIO_BITS 2 /*!< STM32C0xx uses 2 Bits for the Priority Levels */ #define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ /** * @} */ /** @addtogroup Peripheral_interrupt_number_definition * @{ */ /** * @brief stm32c031xx Interrupt Number Definition, according to the selected device * in @ref Library_configuration_section */ /*!< Interrupt Number Definition */ typedef enum { /****** Cortex-M0+ Processor Exceptions Numbers ***************************************************************/ NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ HardFault_IRQn = -13, /*!< 3 Cortex-M Hard Fault Interrupt */ SVC_IRQn = -5, /*!< 11 Cortex-M SV Call Interrupt */ PendSV_IRQn = -2, /*!< 14 Cortex-M Pend SV Interrupt */ SysTick_IRQn = -1, /*!< 15 Cortex-M System Tick Interrupt */ /****** STM32C0xxxx specific Interrupt Numbers ****************************************************************/ WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ RTC_IRQn = 2, /*!< RTC interrupt through the EXTI line 19 & 21 */ FLASH_IRQn = 3, /*!< FLASH global Interrupt */ RCC_IRQn = 4, /*!< RCC global Interrupt */ EXTI0_1_IRQn = 5, /*!< EXTI 0 and 1 Interrupts */ EXTI2_3_IRQn = 6, /*!< EXTI Line 2 and 3 Interrupts */ EXTI4_15_IRQn = 7, /*!< EXTI Line 4 to 15 Interrupts */ DMA1_Channel1_IRQn = 9, /*!< DMA1 Channel 1 Interrupt */ DMA1_Channel2_3_IRQn = 10, /*!< DMA1 Channel 2 and Channel 3 Interrupts */ DMAMUX1_IRQn = 11, /*!< DMAMUX Interrupts */ ADC1_IRQn = 12, /*!< ADC1 Interrupts */ TIM1_BRK_UP_TRG_COM_IRQn = 13, /*!< TIM1 Break, Update, Trigger and Commutation Interrupts */ TIM1_CC_IRQn = 14, /*!< TIM1 Capture Compare Interrupt */ TIM3_IRQn = 16, /*!< TIM3 global Interrupt */ TIM14_IRQn = 19, /*!< TIM14 global Interrupt */ TIM16_IRQn = 21, /*!< TIM16 global Interrupt */ TIM17_IRQn = 22, /*!< TIM17 global Interrupt */ I2C1_IRQn = 23, /*!< I2C1 Interrupt (combined with EXTI 23) */ SPI1_IRQn = 25, /*!< SPI1 Interrupt */ USART1_IRQn = 27, /*!< USART1 Interrupt */ USART2_IRQn = 28, /*!< USART2 Interrupt */ } IRQn_Type; /** * @} */ #include "core_cm0plus.h" /* Cortex-M0+ processor and core peripherals */ #include "system_stm32c0xx.h" #include /** @addtogroup Peripheral_registers_structures * @{ */ /** * @brief Analog to Digital Converter */ typedef struct { __IO uint32_t ISR; /*!< ADC interrupt and status register, Address offset: 0x00 */ __IO uint32_t IER; /*!< ADC interrupt enable register, Address offset: 0x04 */ __IO uint32_t CR; /*!< ADC control register, Address offset: 0x08 */ __IO uint32_t CFGR1; /*!< ADC configuration register 1, Address offset: 0x0C */ __IO uint32_t CFGR2; /*!< ADC configuration register 2, Address offset: 0x10 */ __IO uint32_t SMPR; /*!< ADC sampling time register, Address offset: 0x14 */ uint32_t RESERVED1; /*!< Reserved, 0x18 */ uint32_t RESERVED2; /*!< Reserved, 0x1C */ __IO uint32_t TR1; /*!< ADC analog watchdog 1 threshold register, Address offset: 0x20 */ __IO uint32_t TR2; /*!< ADC analog watchdog 2 threshold register, Address offset: 0x24 */ __IO uint32_t CHSELR; /*!< ADC group regular sequencer register, Address offset: 0x28 */ __IO uint32_t TR3; /*!< ADC analog watchdog 3 threshold register, Address offset: 0x2C */ uint32_t RESERVED3[4]; /*!< Reserved, 0x30 - 0x3C */ __IO uint32_t DR; /*!< ADC group regular data register, Address offset: 0x40 */ uint32_t RESERVED4[23];/*!< Reserved, 0x44 - 0x9C */ __IO uint32_t AWD2CR; /*!< ADC analog watchdog 2 configuration register, Address offset: 0xA0 */ __IO uint32_t AWD3CR; /*!< ADC analog watchdog 3 configuration register, Address offset: 0xA4 */ uint32_t RESERVED5[3]; /*!< Reserved, 0xA8 - 0xB0 */ __IO uint32_t CALFACT; /*!< ADC Calibration factor register, Address offset: 0xB4 */ } ADC_TypeDef; typedef struct { __IO uint32_t CCR; /*!< ADC common configuration register, Address offset: ADC1 base address + 0x308 */ } ADC_Common_TypeDef; /** * @brief CRC calculation unit */ typedef struct { __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */ __IO uint32_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */ __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ uint32_t RESERVED1; /*!< Reserved, 0x0C */ __IO uint32_t INIT; /*!< Initial CRC value register, Address offset: 0x10 */ __IO uint32_t POL; /*!< CRC polynomial register, Address offset: 0x14 */ } CRC_TypeDef; /** * @brief Debug MCU */ typedef struct { __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */ __IO uint32_t CR; /*!< Debug configuration register, Address offset: 0x04 */ __IO uint32_t APBFZ1; /*!< Debug APB freeze register 1, Address offset: 0x08 */ __IO uint32_t APBFZ2; /*!< Debug APB freeze register 2, Address offset: 0x0C */ } DBG_TypeDef; /** * @brief DMA Controller */ typedef struct { __IO uint32_t CCR; /*!< DMA channel x configuration register */ __IO uint32_t CNDTR; /*!< DMA channel x number of data register */ __IO uint32_t CPAR; /*!< DMA channel x peripheral address register */ __IO uint32_t CMAR; /*!< DMA channel x memory address register */ } DMA_Channel_TypeDef; typedef struct { __IO uint32_t ISR; /*!< DMA interrupt status register, Address offset: 0x00 */ __IO uint32_t IFCR; /*!< DMA interrupt flag clear register, Address offset: 0x04 */ } DMA_TypeDef; /** * @brief DMA Multiplexer */ typedef struct { __IO uint32_t CCR; /*!< DMA Multiplexer Channel x Control Register Address offset: 0x0004 * (channel x) */ }DMAMUX_Channel_TypeDef; typedef struct { __IO uint32_t CSR; /*!< DMA Channel Status Register Address offset: 0x0080 */ __IO uint32_t CFR; /*!< DMA Channel Clear Flag Register Address offset: 0x0084 */ }DMAMUX_ChannelStatus_TypeDef; typedef struct { __IO uint32_t RGCR; /*!< DMA Request Generator x Control Register Address offset: 0x0100 + 0x0004 * (Req Gen x) */ }DMAMUX_RequestGen_TypeDef; typedef struct { __IO uint32_t RGSR; /*!< DMA Request Generator Status Register Address offset: 0x0140 */ __IO uint32_t RGCFR; /*!< DMA Request Generator Clear Flag Register Address offset: 0x0144 */ }DMAMUX_RequestGenStatus_TypeDef; /** * @brief Asynch Interrupt/Event Controller (EXTI) */ typedef struct { __IO uint32_t RTSR1; /*!< EXTI Rising Trigger Selection Register 1, Address offset: 0x00 */ __IO uint32_t FTSR1; /*!< EXTI Falling Trigger Selection Register 1, Address offset: 0x04 */ __IO uint32_t SWIER1; /*!< EXTI Software Interrupt event Register 1, Address offset: 0x08 */ __IO uint32_t RPR1; /*!< EXTI Rising Pending Register 1, Address offset: 0x0C */ __IO uint32_t FPR1; /*!< EXTI Falling Pending Register 1, Address offset: 0x10 */ uint32_t RESERVED1[3]; /*!< Reserved 1, 0x14 -- 0x1C */ uint32_t RESERVED2[5]; /*!< Reserved 2, 0x20 -- 0x30 */ uint32_t RESERVED3[11]; /*!< Reserved 3, 0x34 -- 0x5C */ __IO uint32_t EXTICR[4]; /*!< EXTI External Interrupt Configuration Register, 0x60 -- 0x6C */ uint32_t RESERVED4[4]; /*!< Reserved 4, 0x70 -- 0x7C */ __IO uint32_t IMR1; /*!< EXTI Interrupt Mask Register 1, Address offset: 0x80 */ __IO uint32_t EMR1; /*!< EXTI Event Mask Register 1, Address offset: 0x84 */ } EXTI_TypeDef; /** * @brief FLASH Registers */ typedef struct { __IO uint32_t ACR; /*!< FLASH Access Control register, Address offset: 0x00 */ uint32_t RESERVED1; /*!< Reserved1, Address offset: 0x04 */ __IO uint32_t KEYR; /*!< FLASH Key register, Address offset: 0x08 */ __IO uint32_t OPTKEYR; /*!< FLASH Option Key register, Address offset: 0x0C */ __IO uint32_t SR; /*!< FLASH Status register, Address offset: 0x10 */ __IO uint32_t CR; /*!< FLASH Control register, Address offset: 0x14 */ __IO uint32_t ECCR; /*!< FLASH ECC register, Address offset: 0x18 */ uint32_t RESERVED2; /*!< Reserved2, Address offset: 0x1C */ __IO uint32_t OPTR; /*!< FLASH Option register, Address offset: 0x20 */ __IO uint32_t PCROP1ASR; /*!< FLASH Bank PCROP area A Start address register, Address offset: 0x24 */ __IO uint32_t PCROP1AER; /*!< FLASH Bank PCROP area A End address register, Address offset: 0x28 */ __IO uint32_t WRP1AR; /*!< FLASH Bank WRP area A address register, Address offset: 0x2C */ __IO uint32_t WRP1BR; /*!< FLASH Bank WRP area B address register, Address offset: 0x30 */ __IO uint32_t PCROP1BSR; /*!< FLASH Bank PCROP area B Start address register, Address offset: 0x34 */ __IO uint32_t PCROP1BER; /*!< FLASH Bank PCROP area B End address register, Address offset: 0x38 */ uint32_t RESERVED3[17];/*!< Reserved3, Address offset: 0x3C */ __IO uint32_t SECR; /*!< FLASH security register , Address offset: 0x80 */ } FLASH_TypeDef; /** * @brief General Purpose I/O */ typedef struct { __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ __IO uint32_t BSRR; /*!< GPIO port bit set/reset register, Address offset: 0x18 */ __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ __IO uint32_t BRR; /*!< GPIO Bit Reset register, Address offset: 0x28 */ } GPIO_TypeDef; /** * @brief Inter-integrated Circuit Interface */ typedef struct { __IO uint32_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */ __IO uint32_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */ __IO uint32_t OAR1; /*!< I2C Own address 1 register, Address offset: 0x08 */ __IO uint32_t OAR2; /*!< I2C Own address 2 register, Address offset: 0x0C */ __IO uint32_t TIMINGR; /*!< I2C Timing register, Address offset: 0x10 */ __IO uint32_t TIMEOUTR; /*!< I2C Timeout register, Address offset: 0x14 */ __IO uint32_t ISR; /*!< I2C Interrupt and status register, Address offset: 0x18 */ __IO uint32_t ICR; /*!< I2C Interrupt clear register, Address offset: 0x1C */ __IO uint32_t PECR; /*!< I2C PEC register, Address offset: 0x20 */ __IO uint32_t RXDR; /*!< I2C Receive data register, Address offset: 0x24 */ __IO uint32_t TXDR; /*!< I2C Transmit data register, Address offset: 0x28 */ } I2C_TypeDef; /** * @brief Independent WATCHDOG */ typedef struct { __IO uint32_t KR; /*!< IWDG Key register, Address offset: 0x00 */ __IO uint32_t PR; /*!< IWDG Prescaler register, Address offset: 0x04 */ __IO uint32_t RLR; /*!< IWDG Reload register, Address offset: 0x08 */ __IO uint32_t SR; /*!< IWDG Status register, Address offset: 0x0C */ __IO uint32_t WINR; /*!< IWDG Window register, Address offset: 0x10 */ } IWDG_TypeDef; /** * @brief Power Control */ typedef struct { __IO uint32_t CR1; /*!< PWR Power Control Register 1, Address offset: 0x00 */ uint32_t RESERVED1; /*!< Reserved, Address offset: 0x04 */ __IO uint32_t CR3; /*!< PWR Power Control Register 3, Address offset: 0x08 */ __IO uint32_t CR4; /*!< PWR Power Control Register 4, Address offset: 0x0C */ __IO uint32_t SR1; /*!< PWR Power Status Register 1, Address offset: 0x10 */ __IO uint32_t SR2; /*!< PWR Power Status Register 2, Address offset: 0x14 */ __IO uint32_t SCR; /*!< PWR Power Status Clear Register, Address offset: 0x18 */ uint32_t RESERVED2; /*!< Reserved, Address offset: 0x1C */ __IO uint32_t PUCRA; /*!< PWR Pull-Up Control Register of port A, Address offset: 0x20 */ __IO uint32_t PDCRA; /*!< PWR Pull-Down Control Register of port A, Address offset: 0x24 */ __IO uint32_t PUCRB; /*!< PWR Pull-Up Control Register of port B, Address offset: 0x28 */ __IO uint32_t PDCRB; /*!< PWR Pull-Down Control Register of port B, Address offset: 0x2C */ __IO uint32_t PUCRC; /*!< PWR Pull-Up Control Register of port C, Address offset: 0x30 */ __IO uint32_t PDCRC; /*!< PWR Pull-Down Control Register of port C, Address offset: 0x34 */ __IO uint32_t PUCRD; /*!< PWR Pull-Up Control Register of port D, Address offset: 0x38 */ __IO uint32_t PDCRD; /*!< PWR Pull-Down Control Register of port D, Address offset: 0x3C */ uint32_t RESERVED5; /*!< Reserved, Address offset: 0x40 */ uint32_t RESERVED6; /*!< Reserved, Address offset: 0x44 */ __IO uint32_t PUCRF; /*!< PWR Pull-Up Control Register of port F, Address offset: 0x48 */ __IO uint32_t PDCRF; /*!< PWR Pull-Down Control Register of port F, Address offset: 0x4C */ uint32_t RESERVED7[8]; /*!< Reserved, Address offset: 0x50 */ __IO uint32_t BKPREG1; /*!< Backup register 1, Address offset: 0x70 */ __IO uint32_t BKPREG2; /*!< Backup register 2, Address offset: 0x74 */ __IO uint32_t BKPREG3; /*!< Backup register 3, Address offset: 0x78 */ __IO uint32_t BKPREG4; /*!< Backup register 4, Address offset: 0x7C */ } PWR_TypeDef; /** * @brief Reset and Clock Control */ typedef struct { __IO uint32_t CR; /*!< RCC Clock Sources Control Register, Address offset: 0x00 */ __IO uint32_t ICSCR; /*!< RCC Internal Clock Sources Calibration Register, Address offset: 0x04 */ __IO uint32_t CFGR; /*!< RCC Regulated Domain Clocks Configuration Register, Address offset: 0x08 */ uint32_t RESERVED0[3]; /*!< Reserved, Address offset: 0x0C -- 0x14 */ __IO uint32_t CIER; /*!< RCC Clock Interrupt Enable Register, Address offset: 0x18 */ __IO uint32_t CIFR; /*!< RCC Clock Interrupt Flag Register, Address offset: 0x1C */ __IO uint32_t CICR; /*!< RCC Clock Interrupt Clear Register, Address offset: 0x20 */ __IO uint32_t IOPRSTR; /*!< RCC IO port reset register, Address offset: 0x24 */ __IO uint32_t AHBRSTR; /*!< RCC AHB peripherals reset register, Address offset: 0x28 */ __IO uint32_t APBRSTR1; /*!< RCC APB peripherals reset register 1, Address offset: 0x2C */ __IO uint32_t APBRSTR2; /*!< RCC APB peripherals reset register 2, Address offset: 0x30 */ __IO uint32_t IOPENR; /*!< RCC IO port enable register, Address offset: 0x34 */ __IO uint32_t AHBENR; /*!< RCC AHB peripherals clock enable register, Address offset: 0x38 */ __IO uint32_t APBENR1; /*!< RCC APB peripherals clock enable register1, Address offset: 0x3C */ __IO uint32_t APBENR2; /*!< RCC APB peripherals clock enable register2, Address offset: 0x40 */ __IO uint32_t IOPSMENR; /*!< RCC IO port clocks enable in sleep mode register, Address offset: 0x44 */ __IO uint32_t AHBSMENR; /*!< RCC AHB peripheral clocks enable in sleep mode register, Address offset: 0x48 */ __IO uint32_t APBSMENR1; /*!< RCC APB peripheral clocks enable in sleep mode register1, Address offset: 0x4C */ __IO uint32_t APBSMENR2; /*!< RCC APB peripheral clocks enable in sleep mode register2, Address offset: 0x50 */ __IO uint32_t CCIPR; /*!< RCC Peripherals Independent Clocks Configuration Register, Address offset: 0x54 */ __IO uint32_t RESERVED2; /*!< Reserved, Address offset: 0x58 */ __IO uint32_t CSR1; /*!< RCC Control and status Register 1, Address offset: 0x5C */ __IO uint32_t CSR2; /*!< RCC Control and status Register 2, Address offset: 0x60 */ } RCC_TypeDef; /** * @brief Real-Time Clock */ typedef struct { __IO uint32_t TR; /*!< RTC time register, Address offset: 0x00 */ __IO uint32_t DR; /*!< RTC date register, Address offset: 0x04 */ __IO uint32_t SSR; /*!< RTC sub second register, Address offset: 0x08 */ __IO uint32_t ICSR; /*!< RTC initialization control and status register, Address offset: 0x0C */ __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ uint32_t RESERVED0; /*!< Reserved Address offset: 0x14 */ __IO uint32_t CR; /*!< RTC control register, Address offset: 0x18 */ uint32_t RESERVED1; /*!< Reserved Address offset: 0x1C */ uint32_t RESERVED2; /*!< Reserved Address offset: 0x20 */ __IO uint32_t WPR; /*!< RTC write protection register, Address offset: 0x24 */ __IO uint32_t CALR; /*!< RTC calibration register, Address offset: 0x28 */ __IO uint32_t SHIFTR; /*!< RTC shift control register, Address offset: 0x2C */ __IO uint32_t TSTR; /*!< RTC time stamp time register, Address offset: 0x30 */ __IO uint32_t TSDR; /*!< RTC time stamp date register, Address offset: 0x34 */ __IO uint32_t TSSSR; /*!< RTC time-stamp sub second register, Address offset: 0x38 */ uint32_t RESERVED3; /*!< Reserved Address offset: 0x1C */ __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x40 */ __IO uint32_t ALRMASSR; /*!< RTC alarm A sub second register, Address offset: 0x44 */ uint32_t RESERVED4; /*!< Reserved Address offset: 0x48 */ uint32_t RESERVED5; /*!< Reserved Address offset: 0x4C */ __IO uint32_t SR; /*!< RTC Status register, Address offset: 0x50 */ __IO uint32_t MISR; /*!< RTC Masked Interrupt Status register, Address offset: 0x54 */ uint32_t RESERVED6; /*!< Reserved Address offset: 0x58 */ __IO uint32_t SCR; /*!< RTC Status Clear register, Address offset: 0x5C */ } RTC_TypeDef; /** * @brief Serial Peripheral Interface */ typedef struct { __IO uint32_t CR1; /*!< SPI Control register 1 (not used in I2S mode), Address offset: 0x00 */ __IO uint32_t CR2; /*!< SPI Control register 2, Address offset: 0x04 */ __IO uint32_t SR; /*!< SPI Status register, Address offset: 0x08 */ __IO uint32_t DR; /*!< SPI data register, Address offset: 0x0C */ __IO uint32_t CRCPR; /*!< SPI CRC polynomial register (not used in I2S mode), Address offset: 0x10 */ __IO uint32_t RXCRCR; /*!< SPI Rx CRC register (not used in I2S mode), Address offset: 0x14 */ __IO uint32_t TXCRCR; /*!< SPI Tx CRC register (not used in I2S mode), Address offset: 0x18 */ __IO uint32_t I2SCFGR; /*!< SPI_I2S configuration register, Address offset: 0x1C */ __IO uint32_t I2SPR; /*!< SPI_I2S prescaler register, Address offset: 0x20 */ } SPI_TypeDef; /** * @brief System configuration controller */ typedef struct { __IO uint32_t CFGR1; /*!< SYSCFG configuration register 1, Address offset: 0x00 */ uint32_t RESERVED0[5]; /*!< Reserved, 0x04 --0x14 */ __IO uint32_t CFGR2; /*!< SYSCFG configuration register 2, Address offset: 0x18 */ uint32_t RESERVED1[8]; /*!< Reserved 0x1C --0x38 */ __IO uint32_t CFGR3; /*!< SYSCFG configuration register 3, Address offset: 0x3C */ uint32_t RESERVED2[16]; /*!< Reserved 0x40 --0x7C */ __IO uint32_t IT_LINE_SR[32]; /*!< SYSCFG configuration IT_LINE register, Address offset: 0x80 */ } SYSCFG_TypeDef; /** * @brief TIM */ typedef struct { __IO uint32_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ __IO uint32_t CR2; /*!< TIM control register 2, Address offset: 0x04 */ __IO uint32_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */ __IO uint32_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */ __IO uint32_t SR; /*!< TIM status register, Address offset: 0x10 */ __IO uint32_t EGR; /*!< TIM event generation register, Address offset: 0x14 */ __IO uint32_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */ __IO uint32_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */ __IO uint32_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */ __IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */ __IO uint32_t PSC; /*!< TIM prescaler register, Address offset: 0x28 */ __IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */ __IO uint32_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */ __IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */ __IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */ __IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */ __IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */ __IO uint32_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */ __IO uint32_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */ __IO uint32_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x4C */ __IO uint32_t OR1; /*!< TIM option register, Address offset: 0x50 */ __IO uint32_t CCMR3; /*!< TIM capture/compare mode register 3, Address offset: 0x54 */ __IO uint32_t CCR5; /*!< TIM capture/compare register5, Address offset: 0x58 */ __IO uint32_t CCR6; /*!< TIM capture/compare register6, Address offset: 0x5C */ __IO uint32_t AF1; /*!< TIM alternate function register 1, Address offset: 0x60 */ __IO uint32_t AF2; /*!< TIM alternate function register 2, Address offset: 0x64 */ __IO uint32_t TISEL; /*!< TIM Input Selection register, Address offset: 0x68 */ } TIM_TypeDef; /** * @brief Universal Synchronous Asynchronous Receiver Transmitter */ typedef struct { __IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x00 */ __IO uint32_t CR2; /*!< USART Control register 2, Address offset: 0x04 */ __IO uint32_t CR3; /*!< USART Control register 3, Address offset: 0x08 */ __IO uint32_t BRR; /*!< USART Baud rate register, Address offset: 0x0C */ __IO uint32_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x10 */ __IO uint32_t RTOR; /*!< USART Receiver Time Out register, Address offset: 0x14 */ __IO uint32_t RQR; /*!< USART Request register, Address offset: 0x18 */ __IO uint32_t ISR; /*!< USART Interrupt and status register, Address offset: 0x1C */ __IO uint32_t ICR; /*!< USART Interrupt flag Clear register, Address offset: 0x20 */ __IO uint32_t RDR; /*!< USART Receive Data register, Address offset: 0x24 */ __IO uint32_t TDR; /*!< USART Transmit Data register, Address offset: 0x28 */ __IO uint32_t PRESC; /*!< USART Prescaler register, Address offset: 0x2C */ } USART_TypeDef; /** * @brief Window WATCHDOG */ typedef struct { __IO uint32_t CR; /*!< WWDG Control register, Address offset: 0x00 */ __IO uint32_t CFR; /*!< WWDG Configuration register, Address offset: 0x04 */ __IO uint32_t SR; /*!< WWDG Status register, Address offset: 0x08 */ } WWDG_TypeDef; /** @addtogroup Peripheral_memory_map * @{ */ #define FLASH_BASE (0x08000000UL) /*!< FLASH base address */ #define SRAM_BASE (0x20000000UL) /*!< SRAM base address */ #define PERIPH_BASE (0x40000000UL) /*!< Peripheral base address */ #define IOPORT_BASE (0x50000000UL) /*!< IOPORT base address */ #define SRAM_SIZE_MAX (0x00003000UL) /*!< maximum SRAM size (up to 12 KBytes) */ /*!< Peripheral memory map */ #define APBPERIPH_BASE (PERIPH_BASE) #define AHBPERIPH_BASE (PERIPH_BASE + 0x00020000UL) /*!< APB peripherals */ #define TIM3_BASE (APBPERIPH_BASE + 0x00000400UL) #define TIM14_BASE (APBPERIPH_BASE + 0x00002000UL) #define RTC_BASE (APBPERIPH_BASE + 0x00002800UL) #define WWDG_BASE (APBPERIPH_BASE + 0x00002C00UL) #define IWDG_BASE (APBPERIPH_BASE + 0x00003000UL) #define USART2_BASE (APBPERIPH_BASE + 0x00004400UL) #define I2C1_BASE (APBPERIPH_BASE + 0x00005400UL) #define PWR_BASE (APBPERIPH_BASE + 0x00007000UL) #define SYSCFG_BASE (APBPERIPH_BASE + 0x00010000UL) #define ADC1_BASE (APBPERIPH_BASE + 0x00012400UL) #define ADC1_COMMON_BASE (APBPERIPH_BASE + 0x00012708UL) #define ADC_BASE (ADC1_COMMON_BASE) /* Kept for legacy purpose */ #define TIM1_BASE (APBPERIPH_BASE + 0x00012C00UL) #define SPI1_BASE (APBPERIPH_BASE + 0x00013000UL) #define USART1_BASE (APBPERIPH_BASE + 0x00013800UL) #define TIM16_BASE (APBPERIPH_BASE + 0x00014400UL) #define TIM17_BASE (APBPERIPH_BASE + 0x00014800UL) #define DBG_BASE (APBPERIPH_BASE + 0x00015800UL) /*!< AHB peripherals */ #define DMA1_BASE (AHBPERIPH_BASE) #define DMAMUX1_BASE (AHBPERIPH_BASE + 0x00000800UL) #define RCC_BASE (AHBPERIPH_BASE + 0x00001000UL) #define EXTI_BASE (AHBPERIPH_BASE + 0x00001800UL) #define FLASH_R_BASE (AHBPERIPH_BASE + 0x00002000UL) #define CRC_BASE (AHBPERIPH_BASE + 0x00003000UL) #define DMA1_Channel1_BASE (DMA1_BASE + 0x00000008UL) #define DMA1_Channel2_BASE (DMA1_BASE + 0x0000001CUL) #define DMA1_Channel3_BASE (DMA1_BASE + 0x00000030UL) #define DMAMUX1_Channel0_BASE (DMAMUX1_BASE) #define DMAMUX1_Channel1_BASE (DMAMUX1_BASE + 0x00000004UL) #define DMAMUX1_Channel2_BASE (DMAMUX1_BASE + 0x00000008UL) #define DMAMUX1_RequestGenerator0_BASE (DMAMUX1_BASE + 0x00000100UL) #define DMAMUX1_RequestGenerator1_BASE (DMAMUX1_BASE + 0x00000104UL) #define DMAMUX1_RequestGenerator2_BASE (DMAMUX1_BASE + 0x00000108UL) #define DMAMUX1_ChannelStatus_BASE (DMAMUX1_BASE + 0x00000080UL) #define DMAMUX1_RequestGenStatus_BASE (DMAMUX1_BASE + 0x00000140UL) #define DMAMUX1_IdRegisters_BASE (DMAMUX1_BASE + 0x000003EC) /*!< IOPORT */ #define GPIOA_BASE (IOPORT_BASE + 0x00000000UL) #define GPIOB_BASE (IOPORT_BASE + 0x00000400UL) #define GPIOC_BASE (IOPORT_BASE + 0x00000800UL) #define GPIOD_BASE (IOPORT_BASE + 0x00000C00UL) #define GPIOF_BASE (IOPORT_BASE + 0x00001400UL) /*!< Device Electronic Signature */ #define PACKAGE_BASE (0x1FFF7500UL) /*!< Package data register base address */ #define UID_BASE (0x1FFF7550UL) /*!< Unique device ID register base address */ #define FLASHSIZE_BASE (0x1FFF75A0UL) /*!< Flash size data register base address */ /** * @} */ /** @addtogroup Peripheral_declaration * @{ */ #define TIM3 ((TIM_TypeDef *) TIM3_BASE) #define TIM14 ((TIM_TypeDef *) TIM14_BASE) #define RTC ((RTC_TypeDef *) RTC_BASE) #define WWDG ((WWDG_TypeDef *) WWDG_BASE) #define IWDG ((IWDG_TypeDef *) IWDG_BASE) #define USART2 ((USART_TypeDef *) USART2_BASE) #define I2C1 ((I2C_TypeDef *) I2C1_BASE) #define PWR ((PWR_TypeDef *) PWR_BASE) #define RCC ((RCC_TypeDef *) RCC_BASE) #define EXTI ((EXTI_TypeDef *) EXTI_BASE) #define SYSCFG ((SYSCFG_TypeDef *) SYSCFG_BASE) #define TIM1 ((TIM_TypeDef *) TIM1_BASE) #define SPI1 ((SPI_TypeDef *) SPI1_BASE) #define USART1 ((USART_TypeDef *) USART1_BASE) #define TIM16 ((TIM_TypeDef *) TIM16_BASE) #define TIM17 ((TIM_TypeDef *) TIM17_BASE) #define DMA1 ((DMA_TypeDef *) DMA1_BASE) #define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) #define CRC ((CRC_TypeDef *) CRC_BASE) #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) #define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) #define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) #define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) #define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) #define ADC1 ((ADC_TypeDef *) ADC1_BASE) #define ADC1_COMMON ((ADC_Common_TypeDef *) ADC1_COMMON_BASE) #define ADC (ADC1_COMMON) /* Kept for legacy purpose */ #define DMA1_Channel1 ((DMA_Channel_TypeDef *) DMA1_Channel1_BASE) #define DMA1_Channel2 ((DMA_Channel_TypeDef *) DMA1_Channel2_BASE) #define DMA1_Channel3 ((DMA_Channel_TypeDef *) DMA1_Channel3_BASE) #define DMAMUX1 ((DMAMUX_Channel_TypeDef *) DMAMUX1_BASE) #define DMAMUX1_Channel0 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel0_BASE) #define DMAMUX1_Channel1 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel1_BASE) #define DMAMUX1_Channel2 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel2_BASE) #define DMAMUX1_RequestGenerator0 ((DMAMUX_RequestGen_TypeDef *) DMAMUX1_RequestGenerator0_BASE) #define DMAMUX1_RequestGenerator1 ((DMAMUX_RequestGen_TypeDef *) DMAMUX1_RequestGenerator1_BASE) #define DMAMUX1_RequestGenerator2 ((DMAMUX_RequestGen_TypeDef *) DMAMUX1_RequestGenerator2_BASE) #define DMAMUX1_ChannelStatus ((DMAMUX_ChannelStatus_TypeDef *) DMAMUX1_ChannelStatus_BASE) #define DMAMUX1_RequestGenStatus ((DMAMUX_RequestGenStatus_TypeDef *) DMAMUX1_RequestGenStatus_BASE) #define DMAMUX1_IdRegisters ((DMAMUX_IdRegisters_TypeDef *) DMAMUX1_IdRegisters_BASE) #define DBG ((DBG_TypeDef *) DBG_BASE) /** * @} */ /** @addtogroup Exported_constants * @{ */ /** @addtogroup Peripheral_Registers_Bits_Definition * @{ */ /******************************************************************************/ /* Peripheral Registers Bits Definition */ /******************************************************************************/ /******************************************************************************/ /* */ /* Analog to Digital Converter (ADC) */ /* */ /******************************************************************************/ /******************** Bit definition for ADC_ISR register *******************/ #define ADC_ISR_ADRDY_Pos (0U) #define ADC_ISR_ADRDY_Msk (0x1UL << ADC_ISR_ADRDY_Pos) /*!< 0x00000001 */ #define ADC_ISR_ADRDY ADC_ISR_ADRDY_Msk /*!< ADC ready flag */ #define ADC_ISR_EOSMP_Pos (1U) #define ADC_ISR_EOSMP_Msk (0x1UL << ADC_ISR_EOSMP_Pos) /*!< 0x00000002 */ #define ADC_ISR_EOSMP ADC_ISR_EOSMP_Msk /*!< ADC group regular end of sampling flag */ #define ADC_ISR_EOC_Pos (2U) #define ADC_ISR_EOC_Msk (0x1UL << ADC_ISR_EOC_Pos) /*!< 0x00000004 */ #define ADC_ISR_EOC ADC_ISR_EOC_Msk /*!< ADC group regular end of unitary conversion flag */ #define ADC_ISR_EOS_Pos (3U) #define ADC_ISR_EOS_Msk (0x1UL << ADC_ISR_EOS_Pos) /*!< 0x00000008 */ #define ADC_ISR_EOS ADC_ISR_EOS_Msk /*!< ADC group regular end of sequence conversions flag */ #define ADC_ISR_OVR_Pos (4U) #define ADC_ISR_OVR_Msk (0x1UL << ADC_ISR_OVR_Pos) /*!< 0x00000010 */ #define ADC_ISR_OVR ADC_ISR_OVR_Msk /*!< ADC group regular overrun flag */ #define ADC_ISR_AWD1_Pos (7U) #define ADC_ISR_AWD1_Msk (0x1UL << ADC_ISR_AWD1_Pos) /*!< 0x00000080 */ #define ADC_ISR_AWD1 ADC_ISR_AWD1_Msk /*!< ADC analog watchdog 1 flag */ #define ADC_ISR_AWD2_Pos (8U) #define ADC_ISR_AWD2_Msk (0x1UL << ADC_ISR_AWD2_Pos) /*!< 0x00000100 */ #define ADC_ISR_AWD2 ADC_ISR_AWD2_Msk /*!< ADC analog watchdog 2 flag */ #define ADC_ISR_AWD3_Pos (9U) #define ADC_ISR_AWD3_Msk (0x1UL << ADC_ISR_AWD3_Pos) /*!< 0x00000200 */ #define ADC_ISR_AWD3 ADC_ISR_AWD3_Msk /*!< ADC analog watchdog 3 flag */ #define ADC_ISR_EOCAL_Pos (11U) #define ADC_ISR_EOCAL_Msk (0x1UL << ADC_ISR_EOCAL_Pos) /*!< 0x00000800 */ #define ADC_ISR_EOCAL ADC_ISR_EOCAL_Msk /*!< ADC end of calibration flag */ #define ADC_ISR_CCRDY_Pos (13U) #define ADC_ISR_CCRDY_Msk (0x1UL << ADC_ISR_CCRDY_Pos) /*!< 0x00002000 */ #define ADC_ISR_CCRDY ADC_ISR_CCRDY_Msk /*!< ADC channel configuration ready flag */ /* Legacy defines */ #define ADC_ISR_EOSEQ (ADC_ISR_EOS) /******************** Bit definition for ADC_IER register *******************/ #define ADC_IER_ADRDYIE_Pos (0U) #define ADC_IER_ADRDYIE_Msk (0x1UL << ADC_IER_ADRDYIE_Pos) /*!< 0x00000001 */ #define ADC_IER_ADRDYIE ADC_IER_ADRDYIE_Msk /*!< ADC ready interrupt */ #define ADC_IER_EOSMPIE_Pos (1U) #define ADC_IER_EOSMPIE_Msk (0x1UL << ADC_IER_EOSMPIE_Pos) /*!< 0x00000002 */ #define ADC_IER_EOSMPIE ADC_IER_EOSMPIE_Msk /*!< ADC group regular end of sampling interrupt */ #define ADC_IER_EOCIE_Pos (2U) #define ADC_IER_EOCIE_Msk (0x1UL << ADC_IER_EOCIE_Pos) /*!< 0x00000004 */ #define ADC_IER_EOCIE ADC_IER_EOCIE_Msk /*!< ADC group regular end of unitary conversion interrupt */ #define ADC_IER_EOSIE_Pos (3U) #define ADC_IER_EOSIE_Msk (0x1UL << ADC_IER_EOSIE_Pos) /*!< 0x00000008 */ #define ADC_IER_EOSIE ADC_IER_EOSIE_Msk /*!< ADC group regular end of sequence conversions interrupt */ #define ADC_IER_OVRIE_Pos (4U) #define ADC_IER_OVRIE_Msk (0x1UL << ADC_IER_OVRIE_Pos) /*!< 0x00000010 */ #define ADC_IER_OVRIE ADC_IER_OVRIE_Msk /*!< ADC group regular overrun interrupt */ #define ADC_IER_AWD1IE_Pos (7U) #define ADC_IER_AWD1IE_Msk (0x1UL << ADC_IER_AWD1IE_Pos) /*!< 0x00000080 */ #define ADC_IER_AWD1IE ADC_IER_AWD1IE_Msk /*!< ADC analog watchdog 1 interrupt */ #define ADC_IER_AWD2IE_Pos (8U) #define ADC_IER_AWD2IE_Msk (0x1UL << ADC_IER_AWD2IE_Pos) /*!< 0x00000100 */ #define ADC_IER_AWD2IE ADC_IER_AWD2IE_Msk /*!< ADC analog watchdog 2 interrupt */ #define ADC_IER_AWD3IE_Pos (9U) #define ADC_IER_AWD3IE_Msk (0x1UL << ADC_IER_AWD3IE_Pos) /*!< 0x00000200 */ #define ADC_IER_AWD3IE ADC_IER_AWD3IE_Msk /*!< ADC analog watchdog 3 interrupt */ #define ADC_IER_EOCALIE_Pos (11U) #define ADC_IER_EOCALIE_Msk (0x1UL << ADC_IER_EOCALIE_Pos) /*!< 0x00000800 */ #define ADC_IER_EOCALIE ADC_IER_EOCALIE_Msk /*!< ADC end of calibration interrupt */ #define ADC_IER_CCRDYIE_Pos (13U) #define ADC_IER_CCRDYIE_Msk (0x1UL << ADC_IER_CCRDYIE_Pos) /*!< 0x00002000 */ #define ADC_IER_CCRDYIE ADC_IER_CCRDYIE_Msk /*!< ADC channel configuration ready interrupt */ /* Legacy defines */ #define ADC_IER_EOSEQIE (ADC_IER_EOSIE) /******************** Bit definition for ADC_CR register ********************/ #define ADC_CR_ADEN_Pos (0U) #define ADC_CR_ADEN_Msk (0x1UL << ADC_CR_ADEN_Pos) /*!< 0x00000001 */ #define ADC_CR_ADEN ADC_CR_ADEN_Msk /*!< ADC enable */ #define ADC_CR_ADDIS_Pos (1U) #define ADC_CR_ADDIS_Msk (0x1UL << ADC_CR_ADDIS_Pos) /*!< 0x00000002 */ #define ADC_CR_ADDIS ADC_CR_ADDIS_Msk /*!< ADC disable */ #define ADC_CR_ADSTART_Pos (2U) #define ADC_CR_ADSTART_Msk (0x1UL << ADC_CR_ADSTART_Pos) /*!< 0x00000004 */ #define ADC_CR_ADSTART ADC_CR_ADSTART_Msk /*!< ADC group regular conversion start */ #define ADC_CR_ADSTP_Pos (4U) #define ADC_CR_ADSTP_Msk (0x1UL << ADC_CR_ADSTP_Pos) /*!< 0x00000010 */ #define ADC_CR_ADSTP ADC_CR_ADSTP_Msk /*!< ADC group regular conversion stop */ #define ADC_CR_ADVREGEN_Pos (28U) #define ADC_CR_ADVREGEN_Msk (0x1UL << ADC_CR_ADVREGEN_Pos) /*!< 0x10000000 */ #define ADC_CR_ADVREGEN ADC_CR_ADVREGEN_Msk /*!< ADC voltage regulator enable */ #define ADC_CR_ADCAL_Pos (31U) #define ADC_CR_ADCAL_Msk (0x1UL << ADC_CR_ADCAL_Pos) /*!< 0x80000000 */ #define ADC_CR_ADCAL ADC_CR_ADCAL_Msk /*!< ADC calibration */ /******************** Bit definition for ADC_CFGR1 register *****************/ #define ADC_CFGR1_DMAEN_Pos (0U) #define ADC_CFGR1_DMAEN_Msk (0x1UL << ADC_CFGR1_DMAEN_Pos) /*!< 0x00000001 */ #define ADC_CFGR1_DMAEN ADC_CFGR1_DMAEN_Msk /*!< ADC DMA transfer enable */ #define ADC_CFGR1_DMACFG_Pos (1U) #define ADC_CFGR1_DMACFG_Msk (0x1UL << ADC_CFGR1_DMACFG_Pos) /*!< 0x00000002 */ #define ADC_CFGR1_DMACFG ADC_CFGR1_DMACFG_Msk /*!< ADC DMA transfer configuration */ #define ADC_CFGR1_SCANDIR_Pos (2U) #define ADC_CFGR1_SCANDIR_Msk (0x1UL << ADC_CFGR1_SCANDIR_Pos) /*!< 0x00000004 */ #define ADC_CFGR1_SCANDIR ADC_CFGR1_SCANDIR_Msk /*!< ADC group regular sequencer scan direction */ #define ADC_CFGR1_RES_Pos (3U) #define ADC_CFGR1_RES_Msk (0x3UL << ADC_CFGR1_RES_Pos) /*!< 0x00000018 */ #define ADC_CFGR1_RES ADC_CFGR1_RES_Msk /*!< ADC data resolution */ #define ADC_CFGR1_RES_0 (0x1U << ADC_CFGR1_RES_Pos) /*!< 0x00000008 */ #define ADC_CFGR1_RES_1 (0x2U << ADC_CFGR1_RES_Pos) /*!< 0x00000010 */ #define ADC_CFGR1_ALIGN_Pos (5U) #define ADC_CFGR1_ALIGN_Msk (0x1UL << ADC_CFGR1_ALIGN_Pos) /*!< 0x00000020 */ #define ADC_CFGR1_ALIGN ADC_CFGR1_ALIGN_Msk /*!< ADC data alignment */ #define ADC_CFGR1_EXTSEL_Pos (6U) #define ADC_CFGR1_EXTSEL_Msk (0x7UL << ADC_CFGR1_EXTSEL_Pos) /*!< 0x000001C0 */ #define ADC_CFGR1_EXTSEL ADC_CFGR1_EXTSEL_Msk /*!< ADC group regular external trigger source */ #define ADC_CFGR1_EXTSEL_0 (0x1UL << ADC_CFGR1_EXTSEL_Pos) /*!< 0x00000040 */ #define ADC_CFGR1_EXTSEL_1 (0x2UL << ADC_CFGR1_EXTSEL_Pos) /*!< 0x00000080 */ #define ADC_CFGR1_EXTSEL_2 (0x4UL << ADC_CFGR1_EXTSEL_Pos) /*!< 0x00000100 */ #define ADC_CFGR1_EXTEN_Pos (10U) #define ADC_CFGR1_EXTEN_Msk (0x3UL << ADC_CFGR1_EXTEN_Pos) /*!< 0x00000C00 */ #define ADC_CFGR1_EXTEN ADC_CFGR1_EXTEN_Msk /*!< ADC group regular external trigger polarity */ #define ADC_CFGR1_EXTEN_0 (0x1UL << ADC_CFGR1_EXTEN_Pos) /*!< 0x00000400 */ #define ADC_CFGR1_EXTEN_1 (0x2UL << ADC_CFGR1_EXTEN_Pos) /*!< 0x00000800 */ #define ADC_CFGR1_OVRMOD_Pos (12U) #define ADC_CFGR1_OVRMOD_Msk (0x1UL << ADC_CFGR1_OVRMOD_Pos) /*!< 0x00001000 */ #define ADC_CFGR1_OVRMOD ADC_CFGR1_OVRMOD_Msk /*!< ADC group regular overrun configuration */ #define ADC_CFGR1_CONT_Pos (13U) #define ADC_CFGR1_CONT_Msk (0x1UL << ADC_CFGR1_CONT_Pos) /*!< 0x00002000 */ #define ADC_CFGR1_CONT ADC_CFGR1_CONT_Msk /*!< ADC group regular continuous conversion mode */ #define ADC_CFGR1_WAIT_Pos (14U) #define ADC_CFGR1_WAIT_Msk (0x1UL << ADC_CFGR1_WAIT_Pos) /*!< 0x00004000 */ #define ADC_CFGR1_WAIT ADC_CFGR1_WAIT_Msk /*!< ADC low power auto wait */ #define ADC_CFGR1_AUTOFF_Pos (15U) #define ADC_CFGR1_AUTOFF_Msk (0x1UL << ADC_CFGR1_AUTOFF_Pos) /*!< 0x00008000 */ #define ADC_CFGR1_AUTOFF ADC_CFGR1_AUTOFF_Msk /*!< ADC low power auto power off */ #define ADC_CFGR1_DISCEN_Pos (16U) #define ADC_CFGR1_DISCEN_Msk (0x1UL << ADC_CFGR1_DISCEN_Pos) /*!< 0x00010000 */ #define ADC_CFGR1_DISCEN ADC_CFGR1_DISCEN_Msk /*!< ADC group regular sequencer discontinuous mode */ #define ADC_CFGR1_CHSELRMOD_Pos (21U) #define ADC_CFGR1_CHSELRMOD_Msk (0x1UL << ADC_CFGR1_CHSELRMOD_Pos) /*!< 0x00200000 */ #define ADC_CFGR1_CHSELRMOD ADC_CFGR1_CHSELRMOD_Msk /*!< ADC group regular sequencer mode */ #define ADC_CFGR1_AWD1SGL_Pos (22U) #define ADC_CFGR1_AWD1SGL_Msk (0x1UL << ADC_CFGR1_AWD1SGL_Pos) /*!< 0x00400000 */ #define ADC_CFGR1_AWD1SGL ADC_CFGR1_AWD1SGL_Msk /*!< ADC analog watchdog 1 monitoring a single channel or all channels */ #define ADC_CFGR1_AWD1EN_Pos (23U) #define ADC_CFGR1_AWD1EN_Msk (0x1UL << ADC_CFGR1_AWD1EN_Pos) /*!< 0x00800000 */ #define ADC_CFGR1_AWD1EN ADC_CFGR1_AWD1EN_Msk /*!< ADC analog watchdog 1 enable on scope ADC group regular */ #define ADC_CFGR1_AWD1CH_Pos (26U) #define ADC_CFGR1_AWD1CH_Msk (0x1FUL << ADC_CFGR1_AWD1CH_Pos) /*!< 0x7C000000 */ #define ADC_CFGR1_AWD1CH ADC_CFGR1_AWD1CH_Msk /*!< ADC analog watchdog 1 monitored channel selection */ #define ADC_CFGR1_AWD1CH_0 (0x01UL << ADC_CFGR1_AWD1CH_Pos) /*!< 0x04000000 */ #define ADC_CFGR1_AWD1CH_1 (0x02UL << ADC_CFGR1_AWD1CH_Pos) /*!< 0x08000000 */ #define ADC_CFGR1_AWD1CH_2 (0x04UL << ADC_CFGR1_AWD1CH_Pos) /*!< 0x10000000 */ #define ADC_CFGR1_AWD1CH_3 (0x08UL << ADC_CFGR1_AWD1CH_Pos) /*!< 0x20000000 */ #define ADC_CFGR1_AWD1CH_4 (0x10UL << ADC_CFGR1_AWD1CH_Pos) /*!< 0x40000000 */ /* Legacy defines */ #define ADC_CFGR1_AUTDLY (ADC_CFGR1_WAIT) /******************** Bit definition for ADC_CFGR2 register *****************/ #define ADC_CFGR2_OVSE_Pos (0U) #define ADC_CFGR2_OVSE_Msk (0x1UL << ADC_CFGR2_OVSE_Pos) /*!< 0x00000001 */ #define ADC_CFGR2_OVSE ADC_CFGR2_OVSE_Msk /*!< ADC oversampler enable on scope ADC group regular */ #define ADC_CFGR2_OVSR_Pos (2U) #define ADC_CFGR2_OVSR_Msk (0x7UL << ADC_CFGR2_OVSR_Pos) /*!< 0x0000001C */ #define ADC_CFGR2_OVSR ADC_CFGR2_OVSR_Msk /*!< ADC oversampling ratio */ #define ADC_CFGR2_OVSR_0 (0x1UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00000004 */ #define ADC_CFGR2_OVSR_1 (0x2UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00000008 */ #define ADC_CFGR2_OVSR_2 (0x4UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00000010 */ #define ADC_CFGR2_OVSS_Pos (5U) #define ADC_CFGR2_OVSS_Msk (0xFUL << ADC_CFGR2_OVSS_Pos) /*!< 0x000001E0 */ #define ADC_CFGR2_OVSS ADC_CFGR2_OVSS_Msk /*!< ADC oversampling shift */ #define ADC_CFGR2_OVSS_0 (0x1UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000020 */ #define ADC_CFGR2_OVSS_1 (0x2UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000040 */ #define ADC_CFGR2_OVSS_2 (0x4UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000080 */ #define ADC_CFGR2_OVSS_3 (0x8UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000100 */ #define ADC_CFGR2_TOVS_Pos (9U) #define ADC_CFGR2_TOVS_Msk (0x1UL << ADC_CFGR2_TOVS_Pos) /*!< 0x00000200 */ #define ADC_CFGR2_TOVS ADC_CFGR2_TOVS_Msk /*!< ADC oversampling discontinuous mode (triggered mode) for ADC group regular */ #define ADC_CFGR2_LFTRIG_Pos (29U) #define ADC_CFGR2_LFTRIG_Msk (0x1UL << ADC_CFGR2_LFTRIG_Pos) /*!< 0x20000000 */ #define ADC_CFGR2_LFTRIG ADC_CFGR2_LFTRIG_Msk /*!< ADC low frequency trigger mode */ #define ADC_CFGR2_CKMODE_Pos (30U) #define ADC_CFGR2_CKMODE_Msk (0x3UL << ADC_CFGR2_CKMODE_Pos) /*!< 0xC0000000 */ #define ADC_CFGR2_CKMODE ADC_CFGR2_CKMODE_Msk /*!< ADC clock source and prescaler (prescaler only for clock source synchronous) */ #define ADC_CFGR2_CKMODE_1 (0x2UL << ADC_CFGR2_CKMODE_Pos) /*!< 0x80000000 */ #define ADC_CFGR2_CKMODE_0 (0x1UL << ADC_CFGR2_CKMODE_Pos) /*!< 0x40000000 */ /******************** Bit definition for ADC_SMPR register ******************/ #define ADC_SMPR_SMP1_Pos (0U) #define ADC_SMPR_SMP1_Msk (0x7UL << ADC_SMPR_SMP1_Pos) /*!< 0x00000007 */ #define ADC_SMPR_SMP1 ADC_SMPR_SMP1_Msk /*!< ADC group of channels sampling time 1 */ #define ADC_SMPR_SMP1_0 (0x1UL << ADC_SMPR_SMP1_Pos) /*!< 0x00000001 */ #define ADC_SMPR_SMP1_1 (0x2UL << ADC_SMPR_SMP1_Pos) /*!< 0x00000002 */ #define ADC_SMPR_SMP1_2 (0x4UL << ADC_SMPR_SMP1_Pos) /*!< 0x00000004 */ #define ADC_SMPR_SMP2_Pos (4U) #define ADC_SMPR_SMP2_Msk (0x7UL << ADC_SMPR_SMP2_Pos) /*!< 0x00000070 */ #define ADC_SMPR_SMP2 ADC_SMPR_SMP2_Msk /*!< ADC group of channels sampling time 2 */ #define ADC_SMPR_SMP2_0 (0x1UL << ADC_SMPR_SMP2_Pos) /*!< 0x00000010 */ #define ADC_SMPR_SMP2_1 (0x2UL << ADC_SMPR_SMP2_Pos) /*!< 0x00000020 */ #define ADC_SMPR_SMP2_2 (0x4UL << ADC_SMPR_SMP2_Pos) /*!< 0x00000040 */ #define ADC_SMPR_SMPSEL_Pos (8U) #define ADC_SMPR_SMPSEL_Msk (0x7FFFFUL << ADC_SMPR_SMPSEL_Pos) /*!< 0x07FFFF00 */ #define ADC_SMPR_SMPSEL ADC_SMPR_SMPSEL_Msk /*!< ADC all channels sampling time selection */ #define ADC_SMPR_SMPSEL0_Pos (8U) #define ADC_SMPR_SMPSEL0_Msk (0x1UL << ADC_SMPR_SMPSEL0_Pos) /*!< 0x00000100 */ #define ADC_SMPR_SMPSEL0 ADC_SMPR_SMPSEL0_Msk /*!< ADC channel 0 sampling time selection */ #define ADC_SMPR_SMPSEL1_Pos (9U) #define ADC_SMPR_SMPSEL1_Msk (0x1UL << ADC_SMPR_SMPSEL1_Pos) /*!< 0x00000200 */ #define ADC_SMPR_SMPSEL1 ADC_SMPR_SMPSEL1_Msk /*!< ADC channel 1 sampling time selection */ #define ADC_SMPR_SMPSEL2_Pos (10U) #define ADC_SMPR_SMPSEL2_Msk (0x1UL << ADC_SMPR_SMPSEL2_Pos) /*!< 0x00000400 */ #define ADC_SMPR_SMPSEL2 ADC_SMPR_SMPSEL2_Msk /*!< ADC channel 2 sampling time selection */ #define ADC_SMPR_SMPSEL3_Pos (11U) #define ADC_SMPR_SMPSEL3_Msk (0x1UL << ADC_SMPR_SMPSEL3_Pos) /*!< 0x00000800 */ #define ADC_SMPR_SMPSEL3 ADC_SMPR_SMPSEL3_Msk /*!< ADC channel 3 sampling time selection */ #define ADC_SMPR_SMPSEL4_Pos (12U) #define ADC_SMPR_SMPSEL4_Msk (0x1UL << ADC_SMPR_SMPSEL4_Pos) /*!< 0x00001000 */ #define ADC_SMPR_SMPSEL4 ADC_SMPR_SMPSEL4_Msk /*!< ADC channel 4 sampling time selection */ #define ADC_SMPR_SMPSEL5_Pos (13U) #define ADC_SMPR_SMPSEL5_Msk (0x1UL << ADC_SMPR_SMPSEL5_Pos) /*!< 0x00002000 */ #define ADC_SMPR_SMPSEL5 ADC_SMPR_SMPSEL5_Msk /*!< ADC channel 5 sampling time selection */ #define ADC_SMPR_SMPSEL6_Pos (14U) #define ADC_SMPR_SMPSEL6_Msk (0x1UL << ADC_SMPR_SMPSEL6_Pos) /*!< 0x00004000 */ #define ADC_SMPR_SMPSEL6 ADC_SMPR_SMPSEL6_Msk /*!< ADC channel 6 sampling time selection */ #define ADC_SMPR_SMPSEL7_Pos (15U) #define ADC_SMPR_SMPSEL7_Msk (0x1UL << ADC_SMPR_SMPSEL7_Pos) /*!< 0x00008000 */ #define ADC_SMPR_SMPSEL7 ADC_SMPR_SMPSEL7_Msk /*!< ADC channel 7 sampling time selection */ #define ADC_SMPR_SMPSEL8_Pos (16U) #define ADC_SMPR_SMPSEL8_Msk (0x1UL << ADC_SMPR_SMPSEL8_Pos) /*!< 0x00010000 */ #define ADC_SMPR_SMPSEL8 ADC_SMPR_SMPSEL8_Msk /*!< ADC channel 8 sampling time selection */ #define ADC_SMPR_SMPSEL9_Pos (17U) #define ADC_SMPR_SMPSEL9_Msk (0x1UL << ADC_SMPR_SMPSEL9_Pos) /*!< 0x00020000 */ #define ADC_SMPR_SMPSEL9 ADC_SMPR_SMPSEL9_Msk /*!< ADC channel 9 sampling time selection */ #define ADC_SMPR_SMPSEL10_Pos (18U) #define ADC_SMPR_SMPSEL10_Msk (0x1UL << ADC_SMPR_SMPSEL10_Pos) /*!< 0x00040000 */ #define ADC_SMPR_SMPSEL10 ADC_SMPR_SMPSEL10_Msk /*!< ADC channel 10 sampling time selection */ #define ADC_SMPR_SMPSEL11_Pos (19U) #define ADC_SMPR_SMPSEL11_Msk (0x1UL << ADC_SMPR_SMPSEL11_Pos) /*!< 0x00080000 */ #define ADC_SMPR_SMPSEL11 ADC_SMPR_SMPSEL11_Msk /*!< ADC channel 11 sampling time selection */ #define ADC_SMPR_SMPSEL12_Pos (20U) #define ADC_SMPR_SMPSEL12_Msk (0x1UL << ADC_SMPR_SMPSEL12_Pos) /*!< 0x00100000 */ #define ADC_SMPR_SMPSEL12 ADC_SMPR_SMPSEL12_Msk /*!< ADC channel 12 sampling time selection */ #define ADC_SMPR_SMPSEL13_Pos (21U) #define ADC_SMPR_SMPSEL13_Msk (0x1UL << ADC_SMPR_SMPSEL13_Pos) /*!< 0x00200000 */ #define ADC_SMPR_SMPSEL13 ADC_SMPR_SMPSEL13_Msk /*!< ADC channel 13 sampling time selection */ #define ADC_SMPR_SMPSEL14_Pos (22U) #define ADC_SMPR_SMPSEL14_Msk (0x1UL << ADC_SMPR_SMPSEL14_Pos) /*!< 0x00400000 */ #define ADC_SMPR_SMPSEL14 ADC_SMPR_SMPSEL14_Msk /*!< ADC channel 14 sampling time selection */ #define ADC_SMPR_SMPSEL15_Pos (23U) #define ADC_SMPR_SMPSEL15_Msk (0x1UL << ADC_SMPR_SMPSEL15_Pos) /*!< 0x00800000 */ #define ADC_SMPR_SMPSEL15 ADC_SMPR_SMPSEL15_Msk /*!< ADC channel 15 sampling time selection */ #define ADC_SMPR_SMPSEL16_Pos (24U) #define ADC_SMPR_SMPSEL16_Msk (0x1UL << ADC_SMPR_SMPSEL16_Pos) /*!< 0x01000000 */ #define ADC_SMPR_SMPSEL16 ADC_SMPR_SMPSEL16_Msk /*!< ADC channel 16 sampling time selection */ #define ADC_SMPR_SMPSEL17_Pos (25U) #define ADC_SMPR_SMPSEL17_Msk (0x1UL << ADC_SMPR_SMPSEL17_Pos) /*!< 0x02000000 */ #define ADC_SMPR_SMPSEL17 ADC_SMPR_SMPSEL17_Msk /*!< ADC channel 17 sampling time selection */ #define ADC_SMPR_SMPSEL18_Pos (26U) #define ADC_SMPR_SMPSEL18_Msk (0x1UL << ADC_SMPR_SMPSEL18_Pos) /*!< 0x04000000 */ #define ADC_SMPR_SMPSEL18 ADC_SMPR_SMPSEL18_Msk /*!< ADC channel 18 sampling time selection */ /******************** Bit definition for ADC_TR1 register *******************/ #define ADC_TR1_LT1_Pos (0U) #define ADC_TR1_LT1_Msk (0xFFFUL << ADC_TR1_LT1_Pos) /*!< 0x00000FFF */ #define ADC_TR1_LT1 ADC_TR1_LT1_Msk /*!< ADC analog watchdog 1 threshold low */ #define ADC_TR1_LT1_0 (0x001UL << ADC_TR1_LT1_Pos) /*!< 0x00000001 */ #define ADC_TR1_LT1_1 (0x002UL << ADC_TR1_LT1_Pos) /*!< 0x00000002 */ #define ADC_TR1_LT1_2 (0x004UL << ADC_TR1_LT1_Pos) /*!< 0x00000004 */ #define ADC_TR1_LT1_3 (0x008UL << ADC_TR1_LT1_Pos) /*!< 0x00000008 */ #define ADC_TR1_LT1_4 (0x010UL << ADC_TR1_LT1_Pos) /*!< 0x00000010 */ #define ADC_TR1_LT1_5 (0x020UL << ADC_TR1_LT1_Pos) /*!< 0x00000020 */ #define ADC_TR1_LT1_6 (0x040UL << ADC_TR1_LT1_Pos) /*!< 0x00000040 */ #define ADC_TR1_LT1_7 (0x080UL << ADC_TR1_LT1_Pos) /*!< 0x00000080 */ #define ADC_TR1_LT1_8 (0x100UL << ADC_TR1_LT1_Pos) /*!< 0x00000100 */ #define ADC_TR1_LT1_9 (0x200UL << ADC_TR1_LT1_Pos) /*!< 0x00000200 */ #define ADC_TR1_LT1_10 (0x400UL << ADC_TR1_LT1_Pos) /*!< 0x00000400 */ #define ADC_TR1_LT1_11 (0x800UL << ADC_TR1_LT1_Pos) /*!< 0x00000800 */ #define ADC_TR1_HT1_Pos (16U) #define ADC_TR1_HT1_Msk (0xFFFUL << ADC_TR1_HT1_Pos) /*!< 0x0FFF0000 */ #define ADC_TR1_HT1 ADC_TR1_HT1_Msk /*!< ADC Analog watchdog 1 threshold high */ #define ADC_TR1_HT1_0 (0x001UL << ADC_TR1_HT1_Pos) /*!< 0x00010000 */ #define ADC_TR1_HT1_1 (0x002UL << ADC_TR1_HT1_Pos) /*!< 0x00020000 */ #define ADC_TR1_HT1_2 (0x004UL << ADC_TR1_HT1_Pos) /*!< 0x00040000 */ #define ADC_TR1_HT1_3 (0x008UL << ADC_TR1_HT1_Pos) /*!< 0x00080000 */ #define ADC_TR1_HT1_4 (0x010UL << ADC_TR1_HT1_Pos) /*!< 0x00100000 */ #define ADC_TR1_HT1_5 (0x020UL << ADC_TR1_HT1_Pos) /*!< 0x00200000 */ #define ADC_TR1_HT1_6 (0x040UL << ADC_TR1_HT1_Pos) /*!< 0x00400000 */ #define ADC_TR1_HT1_7 (0x080UL << ADC_TR1_HT1_Pos) /*!< 0x00800000 */ #define ADC_TR1_HT1_8 (0x100UL << ADC_TR1_HT1_Pos) /*!< 0x01000000 */ #define ADC_TR1_HT1_9 (0x200UL << ADC_TR1_HT1_Pos) /*!< 0x02000000 */ #define ADC_TR1_HT1_10 (0x400UL << ADC_TR1_HT1_Pos) /*!< 0x04000000 */ #define ADC_TR1_HT1_11 (0x800UL << ADC_TR1_HT1_Pos) /*!< 0x08000000 */ /******************** Bit definition for ADC_TR2 register *******************/ #define ADC_TR2_LT2_Pos (0U) #define ADC_TR2_LT2_Msk (0xFFFUL << ADC_TR2_LT2_Pos) /*!< 0x00000FFF */ #define ADC_TR2_LT2 ADC_TR2_LT2_Msk /*!< ADC analog watchdog 2 threshold low */ #define ADC_TR2_LT2_0 (0x001UL << ADC_TR2_LT2_Pos) /*!< 0x00000001 */ #define ADC_TR2_LT2_1 (0x002UL << ADC_TR2_LT2_Pos) /*!< 0x00000002 */ #define ADC_TR2_LT2_2 (0x004UL << ADC_TR2_LT2_Pos) /*!< 0x00000004 */ #define ADC_TR2_LT2_3 (0x008UL << ADC_TR2_LT2_Pos) /*!< 0x00000008 */ #define ADC_TR2_LT2_4 (0x010UL << ADC_TR2_LT2_Pos) /*!< 0x00000010 */ #define ADC_TR2_LT2_5 (0x020UL << ADC_TR2_LT2_Pos) /*!< 0x00000020 */ #define ADC_TR2_LT2_6 (0x040UL << ADC_TR2_LT2_Pos) /*!< 0x00000040 */ #define ADC_TR2_LT2_7 (0x080UL << ADC_TR2_LT2_Pos) /*!< 0x00000080 */ #define ADC_TR2_LT2_8 (0x100UL << ADC_TR2_LT2_Pos) /*!< 0x00000100 */ #define ADC_TR2_LT2_9 (0x200UL << ADC_TR2_LT2_Pos) /*!< 0x00000200 */ #define ADC_TR2_LT2_10 (0x400UL << ADC_TR2_LT2_Pos) /*!< 0x00000400 */ #define ADC_TR2_LT2_11 (0x800UL << ADC_TR2_LT2_Pos) /*!< 0x00000800 */ #define ADC_TR2_HT2_Pos (16U) #define ADC_TR2_HT2_Msk (0xFFFUL << ADC_TR2_HT2_Pos) /*!< 0x0FFF0000 */ #define ADC_TR2_HT2 ADC_TR2_HT2_Msk /*!< ADC analog watchdog 2 threshold high */ #define ADC_TR2_HT2_0 (0x001UL << ADC_TR2_HT2_Pos) /*!< 0x00010000 */ #define ADC_TR2_HT2_1 (0x002UL << ADC_TR2_HT2_Pos) /*!< 0x00020000 */ #define ADC_TR2_HT2_2 (0x004UL << ADC_TR2_HT2_Pos) /*!< 0x00040000 */ #define ADC_TR2_HT2_3 (0x008UL << ADC_TR2_HT2_Pos) /*!< 0x00080000 */ #define ADC_TR2_HT2_4 (0x010UL << ADC_TR2_HT2_Pos) /*!< 0x00100000 */ #define ADC_TR2_HT2_5 (0x020UL << ADC_TR2_HT2_Pos) /*!< 0x00200000 */ #define ADC_TR2_HT2_6 (0x040UL << ADC_TR2_HT2_Pos) /*!< 0x00400000 */ #define ADC_TR2_HT2_7 (0x080UL << ADC_TR2_HT2_Pos) /*!< 0x00800000 */ #define ADC_TR2_HT2_8 (0x100UL << ADC_TR2_HT2_Pos) /*!< 0x01000000 */ #define ADC_TR2_HT2_9 (0x200UL << ADC_TR2_HT2_Pos) /*!< 0x02000000 */ #define ADC_TR2_HT2_10 (0x400UL << ADC_TR2_HT2_Pos) /*!< 0x04000000 */ #define ADC_TR2_HT2_11 (0x800UL << ADC_TR2_HT2_Pos) /*!< 0x08000000 */ /******************** Bit definition for ADC_CHSELR register ****************/ #define ADC_CHSELR_CHSEL_Pos (0U) #define ADC_CHSELR_CHSEL_Msk (0x7FFFFFUL << ADC_CHSELR_CHSEL_Pos) /*!< 0x0007FFFFF */ #define ADC_CHSELR_CHSEL ADC_CHSELR_CHSEL_Msk /*!< ADC group regular sequencer channels, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL22_Pos (22U) #define ADC_CHSELR_CHSEL22_Msk (0x1UL << ADC_CHSELR_CHSEL22_Pos) /*!< 0x00400000 */ #define ADC_CHSELR_CHSEL22 ADC_CHSELR_CHSEL22_Msk /*!< ADC group regular sequencer channel 22, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL21_Pos (21U) #define ADC_CHSELR_CHSEL21_Msk (0x1UL << ADC_CHSELR_CHSEL21_Pos) /*!< 0x00200000 */ #define ADC_CHSELR_CHSEL21 ADC_CHSELR_CHSEL21_Msk /*!< ADC group regular sequencer channel 21, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL20_Pos (20U) #define ADC_CHSELR_CHSEL20_Msk (0x1UL << ADC_CHSELR_CHSEL20_Pos) /*!< 0x00100000 */ #define ADC_CHSELR_CHSEL20 ADC_CHSELR_CHSEL20_Msk /*!< ADC group regular sequencer channel 20, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL19_Pos (19U) #define ADC_CHSELR_CHSEL19_Msk (0x1UL << ADC_CHSELR_CHSEL19_Pos) /*!< 0x00080000 */ #define ADC_CHSELR_CHSEL19 ADC_CHSELR_CHSEL19_Msk /*!< ADC group regular sequencer channel 19, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL18_Pos (18U) #define ADC_CHSELR_CHSEL18_Msk (0x1UL << ADC_CHSELR_CHSEL18_Pos) /*!< 0x00040000 */ #define ADC_CHSELR_CHSEL18 ADC_CHSELR_CHSEL18_Msk /*!< ADC group regular sequencer channel 18, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL17_Pos (17U) #define ADC_CHSELR_CHSEL17_Msk (0x1UL << ADC_CHSELR_CHSEL17_Pos) /*!< 0x00020000 */ #define ADC_CHSELR_CHSEL17 ADC_CHSELR_CHSEL17_Msk /*!< ADC group regular sequencer channel 17, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL16_Pos (16U) #define ADC_CHSELR_CHSEL16_Msk (0x1UL << ADC_CHSELR_CHSEL16_Pos) /*!< 0x00010000 */ #define ADC_CHSELR_CHSEL16 ADC_CHSELR_CHSEL16_Msk /*!< ADC group regular sequencer channel 16, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL15_Pos (15U) #define ADC_CHSELR_CHSEL15_Msk (0x1UL << ADC_CHSELR_CHSEL15_Pos) /*!< 0x00008000 */ #define ADC_CHSELR_CHSEL15 ADC_CHSELR_CHSEL15_Msk /*!< ADC group regular sequencer channel 15, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL14_Pos (14U) #define ADC_CHSELR_CHSEL14_Msk (0x1UL << ADC_CHSELR_CHSEL14_Pos) /*!< 0x00004000 */ #define ADC_CHSELR_CHSEL14 ADC_CHSELR_CHSEL14_Msk /*!< ADC group regular sequencer channel 14, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL13_Pos (13U) #define ADC_CHSELR_CHSEL13_Msk (0x1UL << ADC_CHSELR_CHSEL13_Pos) /*!< 0x00002000 */ #define ADC_CHSELR_CHSEL13 ADC_CHSELR_CHSEL13_Msk /*!< ADC group regular sequencer channel 13, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL12_Pos (12U) #define ADC_CHSELR_CHSEL12_Msk (0x1UL << ADC_CHSELR_CHSEL12_Pos) /*!< 0x00001000 */ #define ADC_CHSELR_CHSEL12 ADC_CHSELR_CHSEL12_Msk /*!< ADC group regular sequencer channel 12, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL11_Pos (11U) #define ADC_CHSELR_CHSEL11_Msk (0x1UL << ADC_CHSELR_CHSEL11_Pos) /*!< 0x00000800 */ #define ADC_CHSELR_CHSEL11 ADC_CHSELR_CHSEL11_Msk /*!< ADC group regular sequencer channel 11, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL10_Pos (10U) #define ADC_CHSELR_CHSEL10_Msk (0x1UL << ADC_CHSELR_CHSEL10_Pos) /*!< 0x00000400 */ #define ADC_CHSELR_CHSEL10 ADC_CHSELR_CHSEL10_Msk /*!< ADC group regular sequencer channel 10, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL9_Pos (9U) #define ADC_CHSELR_CHSEL9_Msk (0x1UL << ADC_CHSELR_CHSEL9_Pos) /*!< 0x00000200 */ #define ADC_CHSELR_CHSEL9 ADC_CHSELR_CHSEL9_Msk /*!< ADC group regular sequencer channel 9, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL8_Pos (8U) #define ADC_CHSELR_CHSEL8_Msk (0x1UL << ADC_CHSELR_CHSEL8_Pos) /*!< 0x00000100 */ #define ADC_CHSELR_CHSEL8 ADC_CHSELR_CHSEL8_Msk /*!< ADC group regular sequencer channel 8, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL7_Pos (7U) #define ADC_CHSELR_CHSEL7_Msk (0x1UL << ADC_CHSELR_CHSEL7_Pos) /*!< 0x00000080 */ #define ADC_CHSELR_CHSEL7 ADC_CHSELR_CHSEL7_Msk /*!< ADC group regular sequencer channel 7, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL6_Pos (6U) #define ADC_CHSELR_CHSEL6_Msk (0x1UL << ADC_CHSELR_CHSEL6_Pos) /*!< 0x00000040 */ #define ADC_CHSELR_CHSEL6 ADC_CHSELR_CHSEL6_Msk /*!< ADC group regular sequencer channel 6, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL5_Pos (5U) #define ADC_CHSELR_CHSEL5_Msk (0x1UL << ADC_CHSELR_CHSEL5_Pos) /*!< 0x00000020 */ #define ADC_CHSELR_CHSEL5 ADC_CHSELR_CHSEL5_Msk /*!< ADC group regular sequencer channel 5, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL4_Pos (4U) #define ADC_CHSELR_CHSEL4_Msk (0x1UL << ADC_CHSELR_CHSEL4_Pos) /*!< 0x00000010 */ #define ADC_CHSELR_CHSEL4 ADC_CHSELR_CHSEL4_Msk /*!< ADC group regular sequencer channel 4, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL3_Pos (3U) #define ADC_CHSELR_CHSEL3_Msk (0x1UL << ADC_CHSELR_CHSEL3_Pos) /*!< 0x00000008 */ #define ADC_CHSELR_CHSEL3 ADC_CHSELR_CHSEL3_Msk /*!< ADC group regular sequencer channel 3, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL2_Pos (2U) #define ADC_CHSELR_CHSEL2_Msk (0x1UL << ADC_CHSELR_CHSEL2_Pos) /*!< 0x00000004 */ #define ADC_CHSELR_CHSEL2 ADC_CHSELR_CHSEL2_Msk /*!< ADC group regular sequencer channel 2, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL1_Pos (1U) #define ADC_CHSELR_CHSEL1_Msk (0x1UL << ADC_CHSELR_CHSEL1_Pos) /*!< 0x00000002 */ #define ADC_CHSELR_CHSEL1 ADC_CHSELR_CHSEL1_Msk /*!< ADC group regular sequencer channel 1, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_CHSEL0_Pos (0U) #define ADC_CHSELR_CHSEL0_Msk (0x1UL << ADC_CHSELR_CHSEL0_Pos) /*!< 0x00000001 */ #define ADC_CHSELR_CHSEL0 ADC_CHSELR_CHSEL0_Msk /*!< ADC group regular sequencer channel 0, available when ADC_CFGR1_CHSELRMOD is reset */ #define ADC_CHSELR_SQ_ALL_Pos (0U) #define ADC_CHSELR_SQ_ALL_Msk (0xFFFFFFFFUL << ADC_CHSELR_SQ_ALL_Pos) /*!< 0xFFFFFFFF */ #define ADC_CHSELR_SQ_ALL ADC_CHSELR_SQ_ALL_Msk /*!< ADC group regular sequencer all ranks, available when ADC_CFGR1_CHSELRMOD is set */ #define ADC_CHSELR_SQ8_Pos (28U) #define ADC_CHSELR_SQ8_Msk (0xFUL << ADC_CHSELR_SQ8_Pos) /*!< 0xF0000000 */ #define ADC_CHSELR_SQ8 ADC_CHSELR_SQ8_Msk /*!< ADC group regular sequencer rank 8, available when ADC_CFGR1_CHSELRMOD is set */ #define ADC_CHSELR_SQ8_0 (0x1UL << ADC_CHSELR_SQ8_Pos) /*!< 0x10000000 */ #define ADC_CHSELR_SQ8_1 (0x2UL << ADC_CHSELR_SQ8_Pos) /*!< 0x20000000 */ #define ADC_CHSELR_SQ8_2 (0x4UL << ADC_CHSELR_SQ8_Pos) /*!< 0x40000000 */ #define ADC_CHSELR_SQ8_3 (0x8UL << ADC_CHSELR_SQ8_Pos) /*!< 0x80000000 */ #define ADC_CHSELR_SQ7_Pos (24U) #define ADC_CHSELR_SQ7_Msk (0xFUL << ADC_CHSELR_SQ7_Pos) /*!< 0x0F000000 */ #define ADC_CHSELR_SQ7 ADC_CHSELR_SQ7_Msk /*!< ADC group regular sequencer rank 7, available when ADC_CFGR1_CHSELRMOD is set */ #define ADC_CHSELR_SQ7_0 (0x1UL << ADC_CHSELR_SQ7_Pos) /*!< 0x01000000 */ #define ADC_CHSELR_SQ7_1 (0x2UL << ADC_CHSELR_SQ7_Pos) /*!< 0x02000000 */ #define ADC_CHSELR_SQ7_2 (0x4UL << ADC_CHSELR_SQ7_Pos) /*!< 0x04000000 */ #define ADC_CHSELR_SQ7_3 (0x8UL << ADC_CHSELR_SQ7_Pos) /*!< 0x08000000 */ #define ADC_CHSELR_SQ6_Pos (20U) #define ADC_CHSELR_SQ6_Msk (0xFUL << ADC_CHSELR_SQ6_Pos) /*!< 0x00F00000 */ #define ADC_CHSELR_SQ6 ADC_CHSELR_SQ6_Msk /*!< ADC group regular sequencer rank 6, available when ADC_CFGR1_CHSELRMOD is set */ #define ADC_CHSELR_SQ6_0 (0x1UL << ADC_CHSELR_SQ6_Pos) /*!< 0x00100000 */ #define ADC_CHSELR_SQ6_1 (0x2UL << ADC_CHSELR_SQ6_Pos) /*!< 0x00200000 */ #define ADC_CHSELR_SQ6_2 (0x4UL << ADC_CHSELR_SQ6_Pos) /*!< 0x00400000 */ #define ADC_CHSELR_SQ6_3 (0x8UL << ADC_CHSELR_SQ6_Pos) /*!< 0x00800000 */ #define ADC_CHSELR_SQ5_Pos (16U) #define ADC_CHSELR_SQ5_Msk (0xFUL << ADC_CHSELR_SQ5_Pos) /*!< 0x000F0000 */ #define ADC_CHSELR_SQ5 ADC_CHSELR_SQ5_Msk /*!< ADC group regular sequencer rank 5, available when ADC_CFGR1_CHSELRMOD is set */ #define ADC_CHSELR_SQ5_0 (0x1UL << ADC_CHSELR_SQ5_Pos) /*!< 0x00010000 */ #define ADC_CHSELR_SQ5_1 (0x2UL << ADC_CHSELR_SQ5_Pos) /*!< 0x00020000 */ #define ADC_CHSELR_SQ5_2 (0x4UL << ADC_CHSELR_SQ5_Pos) /*!< 0x00040000 */ #define ADC_CHSELR_SQ5_3 (0x8UL << ADC_CHSELR_SQ5_Pos) /*!< 0x00080000 */ #define ADC_CHSELR_SQ4_Pos (12U) #define ADC_CHSELR_SQ4_Msk (0xFUL << ADC_CHSELR_SQ4_Pos) /*!< 0x0000F000 */ #define ADC_CHSELR_SQ4 ADC_CHSELR_SQ4_Msk /*!< ADC group regular sequencer rank 4, available when ADC_CFGR1_CHSELRMOD is set */ #define ADC_CHSELR_SQ4_0 (0x1UL << ADC_CHSELR_SQ4_Pos) /*!< 0x00001000 */ #define ADC_CHSELR_SQ4_1 (0x2UL << ADC_CHSELR_SQ4_Pos) /*!< 0x00002000 */ #define ADC_CHSELR_SQ4_2 (0x4UL << ADC_CHSELR_SQ4_Pos) /*!< 0x00004000 */ #define ADC_CHSELR_SQ4_3 (0x8UL << ADC_CHSELR_SQ4_Pos) /*!< 0x00008000 */ #define ADC_CHSELR_SQ3_Pos (8U) #define ADC_CHSELR_SQ3_Msk (0xFUL << ADC_CHSELR_SQ3_Pos) /*!< 0x00000F00 */ #define ADC_CHSELR_SQ3 ADC_CHSELR_SQ3_Msk /*!< ADC group regular sequencer rank 3, available when ADC_CFGR1_CHSELRMOD is set */ #define ADC_CHSELR_SQ3_0 (0x1UL << ADC_CHSELR_SQ3_Pos) /*!< 0x00000100 */ #define ADC_CHSELR_SQ3_1 (0x2UL << ADC_CHSELR_SQ3_Pos) /*!< 0x00000200 */ #define ADC_CHSELR_SQ3_2 (0x4UL << ADC_CHSELR_SQ3_Pos) /*!< 0x00000400 */ #define ADC_CHSELR_SQ3_3 (0x8UL << ADC_CHSELR_SQ3_Pos) /*!< 0x00000800 */ #define ADC_CHSELR_SQ2_Pos (4U) #define ADC_CHSELR_SQ2_Msk (0xFUL << ADC_CHSELR_SQ2_Pos) /*!< 0x000000F0 */ #define ADC_CHSELR_SQ2 ADC_CHSELR_SQ2_Msk /*!< ADC group regular sequencer rank 2, available when ADC_CFGR1_CHSELRMOD is set */ #define ADC_CHSELR_SQ2_0 (0x1UL << ADC_CHSELR_SQ2_Pos) /*!< 0x00000010 */ #define ADC_CHSELR_SQ2_1 (0x2UL << ADC_CHSELR_SQ2_Pos) /*!< 0x00000020 */ #define ADC_CHSELR_SQ2_2 (0x4UL << ADC_CHSELR_SQ2_Pos) /*!< 0x00000040 */ #define ADC_CHSELR_SQ2_3 (0x8UL << ADC_CHSELR_SQ2_Pos) /*!< 0x00000080 */ #define ADC_CHSELR_SQ1_Pos (0U) #define ADC_CHSELR_SQ1_Msk (0xFUL << ADC_CHSELR_SQ1_Pos) /*!< 0x0000000F */ #define ADC_CHSELR_SQ1 ADC_CHSELR_SQ1_Msk /*!< ADC group regular sequencer rank 1, available when ADC_CFGR1_CHSELRMOD is set */ #define ADC_CHSELR_SQ1_0 (0x1UL << ADC_CHSELR_SQ1_Pos) /*!< 0x00000001 */ #define ADC_CHSELR_SQ1_1 (0x2UL << ADC_CHSELR_SQ1_Pos) /*!< 0x00000002 */ #define ADC_CHSELR_SQ1_2 (0x4UL << ADC_CHSELR_SQ1_Pos) /*!< 0x00000004 */ #define ADC_CHSELR_SQ1_3 (0x8UL << ADC_CHSELR_SQ1_Pos) /*!< 0x00000008 */ /******************** Bit definition for ADC_TR3 register *******************/ #define ADC_TR3_LT3_Pos (0U) #define ADC_TR3_LT3_Msk (0xFFFUL << ADC_TR3_LT3_Pos) /*!< 0x00000FFF */ #define ADC_TR3_LT3 ADC_TR3_LT3_Msk /*!< ADC analog watchdog 3 threshold low */ #define ADC_TR3_LT3_0 (0x001UL << ADC_TR3_LT3_Pos) /*!< 0x00000001 */ #define ADC_TR3_LT3_1 (0x002UL << ADC_TR3_LT3_Pos) /*!< 0x00000002 */ #define ADC_TR3_LT3_2 (0x004UL << ADC_TR3_LT3_Pos) /*!< 0x00000004 */ #define ADC_TR3_LT3_3 (0x008UL << ADC_TR3_LT3_Pos) /*!< 0x00000008 */ #define ADC_TR3_LT3_4 (0x010UL << ADC_TR3_LT3_Pos) /*!< 0x00000010 */ #define ADC_TR3_LT3_5 (0x020UL << ADC_TR3_LT3_Pos) /*!< 0x00000020 */ #define ADC_TR3_LT3_6 (0x040UL << ADC_TR3_LT3_Pos) /*!< 0x00000040 */ #define ADC_TR3_LT3_7 (0x080UL << ADC_TR3_LT3_Pos) /*!< 0x00000080 */ #define ADC_TR3_LT3_8 (0x100UL << ADC_TR3_LT3_Pos) /*!< 0x00000100 */ #define ADC_TR3_LT3_9 (0x200UL << ADC_TR3_LT3_Pos) /*!< 0x00000200 */ #define ADC_TR3_LT3_10 (0x400UL << ADC_TR3_LT3_Pos) /*!< 0x00000400 */ #define ADC_TR3_LT3_11 (0x800UL << ADC_TR3_LT3_Pos) /*!< 0x00000800 */ #define ADC_TR3_HT3_Pos (16U) #define ADC_TR3_HT3_Msk (0xFFFUL << ADC_TR3_HT3_Pos) /*!< 0x0FFF0000 */ #define ADC_TR3_HT3 ADC_TR3_HT3_Msk /*!< ADC analog watchdog 3 threshold high */ #define ADC_TR3_HT3_0 (0x001UL << ADC_TR3_HT3_Pos) /*!< 0x00010000 */ #define ADC_TR3_HT3_1 (0x002UL << ADC_TR3_HT3_Pos) /*!< 0x00020000 */ #define ADC_TR3_HT3_2 (0x004UL << ADC_TR3_HT3_Pos) /*!< 0x00040000 */ #define ADC_TR3_HT3_3 (0x008UL << ADC_TR3_HT3_Pos) /*!< 0x00080000 */ #define ADC_TR3_HT3_4 (0x010UL << ADC_TR3_HT3_Pos) /*!< 0x00100000 */ #define ADC_TR3_HT3_5 (0x020UL << ADC_TR3_HT3_Pos) /*!< 0x00200000 */ #define ADC_TR3_HT3_6 (0x040UL << ADC_TR3_HT3_Pos) /*!< 0x00400000 */ #define ADC_TR3_HT3_7 (0x080UL << ADC_TR3_HT3_Pos) /*!< 0x00800000 */ #define ADC_TR3_HT3_8 (0x100UL << ADC_TR3_HT3_Pos) /*!< 0x01000000 */ #define ADC_TR3_HT3_9 (0x200UL << ADC_TR3_HT3_Pos) /*!< 0x02000000 */ #define ADC_TR3_HT3_10 (0x400UL << ADC_TR3_HT3_Pos) /*!< 0x04000000 */ #define ADC_TR3_HT3_11 (0x800UL << ADC_TR3_HT3_Pos) /*!< 0x08000000 */ /******************** Bit definition for ADC_DR register ********************/ #define ADC_DR_DATA_Pos (0U) #define ADC_DR_DATA_Msk (0xFFFFUL << ADC_DR_DATA_Pos) /*!< 0x0000FFFF */ #define ADC_DR_DATA ADC_DR_DATA_Msk /*!< ADC group regular conversion data */ #define ADC_DR_DATA_0 (0x0001UL << ADC_DR_DATA_Pos) /*!< 0x00000001 */ #define ADC_DR_DATA_1 (0x0002UL << ADC_DR_DATA_Pos) /*!< 0x00000002 */ #define ADC_DR_DATA_2 (0x0004UL << ADC_DR_DATA_Pos) /*!< 0x00000004 */ #define ADC_DR_DATA_3 (0x0008UL << ADC_DR_DATA_Pos) /*!< 0x00000008 */ #define ADC_DR_DATA_4 (0x0010UL << ADC_DR_DATA_Pos) /*!< 0x00000010 */ #define ADC_DR_DATA_5 (0x0020UL << ADC_DR_DATA_Pos) /*!< 0x00000020 */ #define ADC_DR_DATA_6 (0x0040UL << ADC_DR_DATA_Pos) /*!< 0x00000040 */ #define ADC_DR_DATA_7 (0x0080UL << ADC_DR_DATA_Pos) /*!< 0x00000080 */ #define ADC_DR_DATA_8 (0x0100UL << ADC_DR_DATA_Pos) /*!< 0x00000100 */ #define ADC_DR_DATA_9 (0x0200UL << ADC_DR_DATA_Pos) /*!< 0x00000200 */ #define ADC_DR_DATA_10 (0x0400UL << ADC_DR_DATA_Pos) /*!< 0x00000400 */ #define ADC_DR_DATA_11 (0x0800UL << ADC_DR_DATA_Pos) /*!< 0x00000800 */ #define ADC_DR_DATA_12 (0x1000UL << ADC_DR_DATA_Pos) /*!< 0x00001000 */ #define ADC_DR_DATA_13 (0x2000UL << ADC_DR_DATA_Pos) /*!< 0x00002000 */ #define ADC_DR_DATA_14 (0x4000UL << ADC_DR_DATA_Pos) /*!< 0x00004000 */ #define ADC_DR_DATA_15 (0x8000UL << ADC_DR_DATA_Pos) /*!< 0x00008000 */ /******************** Bit definition for ADC_AWD2CR register ****************/ #define ADC_AWD2CR_AWD2CH_Pos (0U) #define ADC_AWD2CR_AWD2CH_Msk (0x7FFFFUL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x0007FFFF */ #define ADC_AWD2CR_AWD2CH ADC_AWD2CR_AWD2CH_Msk /*!< ADC analog watchdog 2 monitored channel selection */ #define ADC_AWD2CR_AWD2CH_0 (0x00001UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000001 */ #define ADC_AWD2CR_AWD2CH_1 (0x00002UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000002 */ #define ADC_AWD2CR_AWD2CH_2 (0x00004UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000004 */ #define ADC_AWD2CR_AWD2CH_3 (0x00008UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000008 */ #define ADC_AWD2CR_AWD2CH_4 (0x00010UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000010 */ #define ADC_AWD2CR_AWD2CH_5 (0x00020UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000020 */ #define ADC_AWD2CR_AWD2CH_6 (0x00040UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000040 */ #define ADC_AWD2CR_AWD2CH_7 (0x00080UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000080 */ #define ADC_AWD2CR_AWD2CH_8 (0x00100UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000100 */ #define ADC_AWD2CR_AWD2CH_9 (0x00200UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000200 */ #define ADC_AWD2CR_AWD2CH_10 (0x00400UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000400 */ #define ADC_AWD2CR_AWD2CH_11 (0x00800UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000800 */ #define ADC_AWD2CR_AWD2CH_12 (0x01000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00001000 */ #define ADC_AWD2CR_AWD2CH_13 (0x02000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00002000 */ #define ADC_AWD2CR_AWD2CH_14 (0x04000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00004000 */ #define ADC_AWD2CR_AWD2CH_15 (0x08000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00008000 */ #define ADC_AWD2CR_AWD2CH_16 (0x10000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00010000 */ #define ADC_AWD2CR_AWD2CH_17 (0x20000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00020000 */ #define ADC_AWD2CR_AWD2CH_18 (0x40000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00040000 */ /******************** Bit definition for ADC_AWD3CR register ****************/ #define ADC_AWD3CR_AWD3CH_Pos (0U) #define ADC_AWD3CR_AWD3CH_Msk (0x7FFFFUL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x0007FFFF */ #define ADC_AWD3CR_AWD3CH ADC_AWD3CR_AWD3CH_Msk /*!< ADC analog watchdog 3 monitored channel selection */ #define ADC_AWD3CR_AWD3CH_0 (0x00001UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000001 */ #define ADC_AWD3CR_AWD3CH_1 (0x00002UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000002 */ #define ADC_AWD3CR_AWD3CH_2 (0x00004UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000004 */ #define ADC_AWD3CR_AWD3CH_3 (0x00008UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000008 */ #define ADC_AWD3CR_AWD3CH_4 (0x00010UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000010 */ #define ADC_AWD3CR_AWD3CH_5 (0x00020UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000020 */ #define ADC_AWD3CR_AWD3CH_6 (0x00040UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000040 */ #define ADC_AWD3CR_AWD3CH_7 (0x00080UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000080 */ #define ADC_AWD3CR_AWD3CH_8 (0x00100UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000100 */ #define ADC_AWD3CR_AWD3CH_9 (0x00200UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000200 */ #define ADC_AWD3CR_AWD3CH_10 (0x00400UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000400 */ #define ADC_AWD3CR_AWD3CH_11 (0x00800UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000800 */ #define ADC_AWD3CR_AWD3CH_12 (0x01000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00001000 */ #define ADC_AWD3CR_AWD3CH_13 (0x02000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00002000 */ #define ADC_AWD3CR_AWD3CH_14 (0x04000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00004000 */ #define ADC_AWD3CR_AWD3CH_15 (0x08000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00008000 */ #define ADC_AWD3CR_AWD3CH_16 (0x10000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00010000 */ #define ADC_AWD3CR_AWD3CH_17 (0x20000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00020000 */ #define ADC_AWD3CR_AWD3CH_18 (0x40000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00040000 */ /******************** Bit definition for ADC_CALFACT register ***************/ #define ADC_CALFACT_CALFACT_Pos (0U) #define ADC_CALFACT_CALFACT_Msk (0x7FUL << ADC_CALFACT_CALFACT_Pos) /*!< 0x0000007F */ #define ADC_CALFACT_CALFACT ADC_CALFACT_CALFACT_Msk /*!< ADC calibration factor in single-ended mode */ #define ADC_CALFACT_CALFACT_0 (0x01UL << ADC_CALFACT_CALFACT_Pos) /*!< 0x00000001 */ #define ADC_CALFACT_CALFACT_1 (0x02UL << ADC_CALFACT_CALFACT_Pos) /*!< 0x00000002 */ #define ADC_CALFACT_CALFACT_2 (0x04UL << ADC_CALFACT_CALFACT_Pos) /*!< 0x00000004 */ #define ADC_CALFACT_CALFACT_3 (0x08UL << ADC_CALFACT_CALFACT_Pos) /*!< 0x00000008 */ #define ADC_CALFACT_CALFACT_4 (0x10UL << ADC_CALFACT_CALFACT_Pos) /*!< 0x00000010 */ #define ADC_CALFACT_CALFACT_5 (0x20UL << ADC_CALFACT_CALFACT_Pos) /*!< 0x00000020 */ #define ADC_CALFACT_CALFACT_6 (0x40UL << ADC_CALFACT_CALFACT_Pos) /*!< 0x00000040 */ /************************* ADC Common registers *****************************/ /******************** Bit definition for ADC_CCR register *******************/ #define ADC_CCR_PRESC_Pos (18U) #define ADC_CCR_PRESC_Msk (0xFUL << ADC_CCR_PRESC_Pos) /*!< 0x003C0000 */ #define ADC_CCR_PRESC ADC_CCR_PRESC_Msk /*!< ADC common clock prescaler, only for clock source asynchronous */ #define ADC_CCR_PRESC_0 (0x1UL << ADC_CCR_PRESC_Pos) /*!< 0x00040000 */ #define ADC_CCR_PRESC_1 (0x2UL << ADC_CCR_PRESC_Pos) /*!< 0x00080000 */ #define ADC_CCR_PRESC_2 (0x4UL << ADC_CCR_PRESC_Pos) /*!< 0x00100000 */ #define ADC_CCR_PRESC_3 (0x8UL << ADC_CCR_PRESC_Pos) /*!< 0x00200000 */ #define ADC_CCR_VREFEN_Pos (22U) #define ADC_CCR_VREFEN_Msk (0x1UL << ADC_CCR_VREFEN_Pos) /*!< 0x00400000 */ #define ADC_CCR_VREFEN ADC_CCR_VREFEN_Msk /*!< ADC internal path to VrefInt enable */ #define ADC_CCR_TSEN_Pos (23U) #define ADC_CCR_TSEN_Msk (0x1UL << ADC_CCR_TSEN_Pos) /*!< 0x00800000 */ #define ADC_CCR_TSEN ADC_CCR_TSEN_Msk /*!< ADC internal path to temperature sensor enable */ /* Legacy */ #define ADC_CCR_LFMEN_Pos (25U) #define ADC_CCR_LFMEN_Msk (0x1UL << ADC_CCR_LFMEN_Pos) /*!< 0x02000000 */ #define ADC_CCR_LFMEN ADC_CCR_LFMEN_Msk /*!< Legacy feature, useless on STM32C0 (ADC common clock low frequency mode is automatically managed by ADC peripheral on STM32C0) */ /******************************************************************************/ /* */ /* CRC calculation unit */ /* */ /******************************************************************************/ /******************* Bit definition for CRC_DR register *********************/ #define CRC_DR_DR_Pos (0U) #define CRC_DR_DR_Msk (0xFFFFFFFFUL << CRC_DR_DR_Pos) /*!< 0xFFFFFFFF */ #define CRC_DR_DR CRC_DR_DR_Msk /*!< Data register bits */ /******************* Bit definition for CRC_IDR register ********************/ #define CRC_IDR_IDR_Pos (0U) #define CRC_IDR_IDR_Msk (0xFFFFFFFFUL << CRC_IDR_IDR_Pos) /*!< 0xFFFFFFFF */ #define CRC_IDR_IDR CRC_IDR_IDR_Msk /*!< General-purpose 32-bits data register bits */ /******************** Bit definition for CRC_CR register ********************/ #define CRC_CR_RESET_Pos (0U) #define CRC_CR_RESET_Msk (0x1UL << CRC_CR_RESET_Pos) /*!< 0x00000001 */ #define CRC_CR_RESET CRC_CR_RESET_Msk /*!< RESET the CRC computation unit bit */ #define CRC_CR_POLYSIZE_Pos (3U) #define CRC_CR_POLYSIZE_Msk (0x3UL << CRC_CR_POLYSIZE_Pos) /*!< 0x00000018 */ #define CRC_CR_POLYSIZE CRC_CR_POLYSIZE_Msk /*!< Polynomial size bits */ #define CRC_CR_POLYSIZE_0 (0x1UL << CRC_CR_POLYSIZE_Pos) /*!< 0x00000008 */ #define CRC_CR_POLYSIZE_1 (0x2UL << CRC_CR_POLYSIZE_Pos) /*!< 0x00000010 */ #define CRC_CR_REV_IN_Pos (5U) #define CRC_CR_REV_IN_Msk (0x3UL << CRC_CR_REV_IN_Pos) /*!< 0x00000060 */ #define CRC_CR_REV_IN CRC_CR_REV_IN_Msk /*!< REV_IN Reverse Input Data bits */ #define CRC_CR_REV_IN_0 (0x1UL << CRC_CR_REV_IN_Pos) /*!< 0x00000020 */ #define CRC_CR_REV_IN_1 (0x2UL << CRC_CR_REV_IN_Pos) /*!< 0x00000040 */ #define CRC_CR_REV_OUT_Pos (7U) #define CRC_CR_REV_OUT_Msk (0x1UL << CRC_CR_REV_OUT_Pos) /*!< 0x00000080 */ #define CRC_CR_REV_OUT CRC_CR_REV_OUT_Msk /*!< REV_OUT Reverse Output Data bits */ /******************* Bit definition for CRC_INIT register *******************/ #define CRC_INIT_INIT_Pos (0U) #define CRC_INIT_INIT_Msk (0xFFFFFFFFUL << CRC_INIT_INIT_Pos) /*!< 0xFFFFFFFF */ #define CRC_INIT_INIT CRC_INIT_INIT_Msk /*!< Initial CRC value bits */ /******************* Bit definition for CRC_POL register ********************/ #define CRC_POL_POL_Pos (0U) #define CRC_POL_POL_Msk (0xFFFFFFFFUL << CRC_POL_POL_Pos) /*!< 0xFFFFFFFF */ #define CRC_POL_POL CRC_POL_POL_Msk /*!< Coefficients of the polynomial */ /******************************************************************************/ /* */ /* Debug MCU */ /* */ /******************************************************************************/ /********************************* DEVICE ID ********************************/ #define DEV_ID 0x453UL /******************** Bit definition for DBG_IDCODE register *************/ #define DBG_IDCODE_DEV_ID_Pos (0U) #define DBG_IDCODE_DEV_ID_Msk (0xFFFUL << DBG_IDCODE_DEV_ID_Pos) /*!< 0x00000FFF */ #define DBG_IDCODE_DEV_ID DBG_IDCODE_DEV_ID_Msk #define DBG_IDCODE_REV_ID_Pos (16U) #define DBG_IDCODE_REV_ID_Msk (0xFFFFUL << DBG_IDCODE_REV_ID_Pos) /*!< 0xFFFF0000 */ #define DBG_IDCODE_REV_ID DBG_IDCODE_REV_ID_Msk /******************** Bit definition for DBG_CR register *****************/ #define DBG_CR_DBG_STOP_Pos (1U) #define DBG_CR_DBG_STOP_Msk (0x1UL << DBG_CR_DBG_STOP_Pos) /*!< 0x00000002 */ #define DBG_CR_DBG_STOP DBG_CR_DBG_STOP_Msk #define DBG_CR_DBG_STANDBY_Pos (2U) #define DBG_CR_DBG_STANDBY_Msk (0x1UL << DBG_CR_DBG_STANDBY_Pos) /*!< 0x00000004 */ #define DBG_CR_DBG_STANDBY DBG_CR_DBG_STANDBY_Msk /******************** Bit definition for DBG_APB_FZ1 register ***********/ #define DBG_APB_FZ1_DBG_TIM3_STOP_Pos (1U) #define DBG_APB_FZ1_DBG_TIM3_STOP_Msk (0x1UL << DBG_APB_FZ1_DBG_TIM3_STOP_Pos) /*!< 0x00000002 */ #define DBG_APB_FZ1_DBG_TIM3_STOP DBG_APB_FZ1_DBG_TIM3_STOP_Msk #define DBG_APB_FZ1_DBG_RTC_STOP_Pos (10U) #define DBG_APB_FZ1_DBG_RTC_STOP_Msk (0x1UL << DBG_APB_FZ1_DBG_RTC_STOP_Pos) /*!< 0x00000400 */ #define DBG_APB_FZ1_DBG_RTC_STOP DBG_APB_FZ1_DBG_RTC_STOP_Msk #define DBG_APB_FZ1_DBG_WWDG_STOP_Pos (11U) #define DBG_APB_FZ1_DBG_WWDG_STOP_Msk (0x1UL << DBG_APB_FZ1_DBG_WWDG_STOP_Pos) /*!< 0x00000800 */ #define DBG_APB_FZ1_DBG_WWDG_STOP DBG_APB_FZ1_DBG_WWDG_STOP_Msk #define DBG_APB_FZ1_DBG_IWDG_STOP_Pos (12U) #define DBG_APB_FZ1_DBG_IWDG_STOP_Msk (0x1UL << DBG_APB_FZ1_DBG_IWDG_STOP_Pos) /*!< 0x00001000 */ #define DBG_APB_FZ1_DBG_IWDG_STOP DBG_APB_FZ1_DBG_IWDG_STOP_Msk #define DBG_APB_FZ1_DBG_I2C1_SMBUS_TIMEOUT_STOP_Pos (21U) #define DBG_APB_FZ1_DBG_I2C1_SMBUS_TIMEOUT_STOP_Msk (0x1UL << DBG_APB_FZ1_DBG_I2C1_SMBUS_TIMEOUT_STOP_Pos) /*!< 0x00200000 */ #define DBG_APB_FZ1_DBG_I2C1_SMBUS_TIMEOUT_STOP DBG_APB_FZ1_DBG_I2C1_SMBUS_TIMEOUT_STOP_Msk /******************** Bit definition for DBG_APB_FZ2 register ************/ #define DBG_APB_FZ2_DBG_TIM1_STOP_Pos (11U) #define DBG_APB_FZ2_DBG_TIM1_STOP_Msk (0x1UL << DBG_APB_FZ2_DBG_TIM1_STOP_Pos) /*!< 0x00000800 */ #define DBG_APB_FZ2_DBG_TIM1_STOP DBG_APB_FZ2_DBG_TIM1_STOP_Msk #define DBG_APB_FZ2_DBG_TIM14_STOP_Pos (15U) #define DBG_APB_FZ2_DBG_TIM14_STOP_Msk (0x1UL << DBG_APB_FZ2_DBG_TIM14_STOP_Pos) /*!< 0x00008000 */ #define DBG_APB_FZ2_DBG_TIM14_STOP DBG_APB_FZ2_DBG_TIM14_STOP_Msk #define DBG_APB_FZ2_DBG_TIM16_STOP_Pos (17U) #define DBG_APB_FZ2_DBG_TIM16_STOP_Msk (0x1UL << DBG_APB_FZ2_DBG_TIM16_STOP_Pos) /*!< 0x00020000 */ #define DBG_APB_FZ2_DBG_TIM16_STOP DBG_APB_FZ2_DBG_TIM16_STOP_Msk #define DBG_APB_FZ2_DBG_TIM17_STOP_Pos (18U) #define DBG_APB_FZ2_DBG_TIM17_STOP_Msk (0x1UL << DBG_APB_FZ2_DBG_TIM17_STOP_Pos) /*!< 0x00040000 */ #define DBG_APB_FZ2_DBG_TIM17_STOP DBG_APB_FZ2_DBG_TIM17_STOP_Msk /******************************************************************************/ /* */ /* DMA Controller (DMA) */ /* */ /******************************************************************************/ /******************* Bit definition for DMA_ISR register ********************/ #define DMA_ISR_GIF1_Pos (0U) #define DMA_ISR_GIF1_Msk (0x1UL << DMA_ISR_GIF1_Pos) /*!< 0x00000001 */ #define DMA_ISR_GIF1 DMA_ISR_GIF1_Msk /*!< Channel 1 Global interrupt flag */ #define DMA_ISR_TCIF1_Pos (1U) #define DMA_ISR_TCIF1_Msk (0x1UL << DMA_ISR_TCIF1_Pos) /*!< 0x00000002 */ #define DMA_ISR_TCIF1 DMA_ISR_TCIF1_Msk /*!< Channel 1 Transfer Complete flag */ #define DMA_ISR_HTIF1_Pos (2U) #define DMA_ISR_HTIF1_Msk (0x1UL << DMA_ISR_HTIF1_Pos) /*!< 0x00000004 */ #define DMA_ISR_HTIF1 DMA_ISR_HTIF1_Msk /*!< Channel 1 Half Transfer flag */ #define DMA_ISR_TEIF1_Pos (3U) #define DMA_ISR_TEIF1_Msk (0x1UL << DMA_ISR_TEIF1_Pos) /*!< 0x00000008 */ #define DMA_ISR_TEIF1 DMA_ISR_TEIF1_Msk /*!< Channel 1 Transfer Error flag */ #define DMA_ISR_GIF2_Pos (4U) #define DMA_ISR_GIF2_Msk (0x1UL << DMA_ISR_GIF2_Pos) /*!< 0x00000010 */ #define DMA_ISR_GIF2 DMA_ISR_GIF2_Msk /*!< Channel 2 Global interrupt flag */ #define DMA_ISR_TCIF2_Pos (5U) #define DMA_ISR_TCIF2_Msk (0x1UL << DMA_ISR_TCIF2_Pos) /*!< 0x00000020 */ #define DMA_ISR_TCIF2 DMA_ISR_TCIF2_Msk /*!< Channel 2 Transfer Complete flag */ #define DMA_ISR_HTIF2_Pos (6U) #define DMA_ISR_HTIF2_Msk (0x1UL << DMA_ISR_HTIF2_Pos) /*!< 0x00000040 */ #define DMA_ISR_HTIF2 DMA_ISR_HTIF2_Msk /*!< Channel 2 Half Transfer flag */ #define DMA_ISR_TEIF2_Pos (7U) #define DMA_ISR_TEIF2_Msk (0x1UL << DMA_ISR_TEIF2_Pos) /*!< 0x00000080 */ #define DMA_ISR_TEIF2 DMA_ISR_TEIF2_Msk /*!< Channel 2 Transfer Error flag */ #define DMA_ISR_GIF3_Pos (8U) #define DMA_ISR_GIF3_Msk (0x1UL << DMA_ISR_GIF3_Pos) /*!< 0x00000100 */ #define DMA_ISR_GIF3 DMA_ISR_GIF3_Msk /*!< Channel 3 Global interrupt flag */ #define DMA_ISR_TCIF3_Pos (9U) #define DMA_ISR_TCIF3_Msk (0x1UL << DMA_ISR_TCIF3_Pos) /*!< 0x00000200 */ #define DMA_ISR_TCIF3 DMA_ISR_TCIF3_Msk /*!< Channel 3 Transfer Complete flag */ #define DMA_ISR_HTIF3_Pos (10U) #define DMA_ISR_HTIF3_Msk (0x1UL << DMA_ISR_HTIF3_Pos) /*!< 0x00000400 */ #define DMA_ISR_HTIF3 DMA_ISR_HTIF3_Msk /*!< Channel 3 Half Transfer flag */ #define DMA_ISR_TEIF3_Pos (11U) #define DMA_ISR_TEIF3_Msk (0x1UL << DMA_ISR_TEIF3_Pos) /*!< 0x00000800 */ #define DMA_ISR_TEIF3 DMA_ISR_TEIF3_Msk /*!< Channel 3 Transfer Error flag */ /******************* Bit definition for DMA_IFCR register *******************/ #define DMA_IFCR_CGIF1_Pos (0U) #define DMA_IFCR_CGIF1_Msk (0x1UL << DMA_IFCR_CGIF1_Pos) /*!< 0x00000001 */ #define DMA_IFCR_CGIF1 DMA_IFCR_CGIF1_Msk /*!< Channel 1 Global interrupt clearr */ #define DMA_IFCR_CTCIF1_Pos (1U) #define DMA_IFCR_CTCIF1_Msk (0x1UL << DMA_IFCR_CTCIF1_Pos) /*!< 0x00000002 */ #define DMA_IFCR_CTCIF1 DMA_IFCR_CTCIF1_Msk /*!< Channel 1 Transfer Complete clear */ #define DMA_IFCR_CHTIF1_Pos (2U) #define DMA_IFCR_CHTIF1_Msk (0x1UL << DMA_IFCR_CHTIF1_Pos) /*!< 0x00000004 */ #define DMA_IFCR_CHTIF1 DMA_IFCR_CHTIF1_Msk /*!< Channel 1 Half Transfer clear */ #define DMA_IFCR_CTEIF1_Pos (3U) #define DMA_IFCR_CTEIF1_Msk (0x1UL << DMA_IFCR_CTEIF1_Pos) /*!< 0x00000008 */ #define DMA_IFCR_CTEIF1 DMA_IFCR_CTEIF1_Msk /*!< Channel 1 Transfer Error clear */ #define DMA_IFCR_CGIF2_Pos (4U) #define DMA_IFCR_CGIF2_Msk (0x1UL << DMA_IFCR_CGIF2_Pos) /*!< 0x00000010 */ #define DMA_IFCR_CGIF2 DMA_IFCR_CGIF2_Msk /*!< Channel 2 Global interrupt clear */ #define DMA_IFCR_CTCIF2_Pos (5U) #define DMA_IFCR_CTCIF2_Msk (0x1UL << DMA_IFCR_CTCIF2_Pos) /*!< 0x00000020 */ #define DMA_IFCR_CTCIF2 DMA_IFCR_CTCIF2_Msk /*!< Channel 2 Transfer Complete clear */ #define DMA_IFCR_CHTIF2_Pos (6U) #define DMA_IFCR_CHTIF2_Msk (0x1UL << DMA_IFCR_CHTIF2_Pos) /*!< 0x00000040 */ #define DMA_IFCR_CHTIF2 DMA_IFCR_CHTIF2_Msk /*!< Channel 2 Half Transfer clear */ #define DMA_IFCR_CTEIF2_Pos (7U) #define DMA_IFCR_CTEIF2_Msk (0x1UL << DMA_IFCR_CTEIF2_Pos) /*!< 0x00000080 */ #define DMA_IFCR_CTEIF2 DMA_IFCR_CTEIF2_Msk /*!< Channel 2 Transfer Error clear */ #define DMA_IFCR_CGIF3_Pos (8U) #define DMA_IFCR_CGIF3_Msk (0x1UL << DMA_IFCR_CGIF3_Pos) /*!< 0x00000100 */ #define DMA_IFCR_CGIF3 DMA_IFCR_CGIF3_Msk /*!< Channel 3 Global interrupt clear */ #define DMA_IFCR_CTCIF3_Pos (9U) #define DMA_IFCR_CTCIF3_Msk (0x1UL << DMA_IFCR_CTCIF3_Pos) /*!< 0x00000200 */ #define DMA_IFCR_CTCIF3 DMA_IFCR_CTCIF3_Msk /*!< Channel 3 Transfer Complete clear */ #define DMA_IFCR_CHTIF3_Pos (10U) #define DMA_IFCR_CHTIF3_Msk (0x1UL << DMA_IFCR_CHTIF3_Pos) /*!< 0x00000400 */ #define DMA_IFCR_CHTIF3 DMA_IFCR_CHTIF3_Msk /*!< Channel 3 Half Transfer clear */ #define DMA_IFCR_CTEIF3_Pos (11U) #define DMA_IFCR_CTEIF3_Msk (0x1UL << DMA_IFCR_CTEIF3_Pos) /*!< 0x00000800 */ #define DMA_IFCR_CTEIF3 DMA_IFCR_CTEIF3_Msk /*!< Channel 3 Transfer Error clear */ #define DMA_IFCR_CGIF4_Pos (12U) #define DMA_IFCR_CGIF4_Msk (0x1UL << DMA_IFCR_CGIF4_Pos) /*!< 0x00001000 */ #define DMA_IFCR_CGIF4 DMA_IFCR_CGIF4_Msk /*!< Channel 4 Global interrupt clear */ #define DMA_IFCR_CTCIF4_Pos (13U) #define DMA_IFCR_CTCIF4_Msk (0x1UL << DMA_IFCR_CTCIF4_Pos) /*!< 0x00002000 */ #define DMA_IFCR_CTCIF4 DMA_IFCR_CTCIF4_Msk /*!< Channel 4 Transfer Complete clear */ #define DMA_IFCR_CHTIF4_Pos (14U) #define DMA_IFCR_CHTIF4_Msk (0x1UL << DMA_IFCR_CHTIF4_Pos) /*!< 0x00004000 */ #define DMA_IFCR_CHTIF4 DMA_IFCR_CHTIF4_Msk /*!< Channel 4 Half Transfer clear */ #define DMA_IFCR_CTEIF4_Pos (15U) #define DMA_IFCR_CTEIF4_Msk (0x1UL << DMA_IFCR_CTEIF4_Pos) /*!< 0x00008000 */ #define DMA_IFCR_CTEIF4 DMA_IFCR_CTEIF4_Msk /*!< Channel 4 Transfer Error clear */ /******************* Bit definition for DMA_CCR register ********************/ #define DMA_CCR_EN_Pos (0U) #define DMA_CCR_EN_Msk (0x1UL << DMA_CCR_EN_Pos) /*!< 0x00000001 */ #define DMA_CCR_EN DMA_CCR_EN_Msk /*!< Channel enable */ #define DMA_CCR_TCIE_Pos (1U) #define DMA_CCR_TCIE_Msk (0x1UL << DMA_CCR_TCIE_Pos) /*!< 0x00000002 */ #define DMA_CCR_TCIE DMA_CCR_TCIE_Msk /*!< Transfer complete interrupt enable */ #define DMA_CCR_HTIE_Pos (2U) #define DMA_CCR_HTIE_Msk (0x1UL << DMA_CCR_HTIE_Pos) /*!< 0x00000004 */ #define DMA_CCR_HTIE DMA_CCR_HTIE_Msk /*!< Half Transfer interrupt enable */ #define DMA_CCR_TEIE_Pos (3U) #define DMA_CCR_TEIE_Msk (0x1UL << DMA_CCR_TEIE_Pos) /*!< 0x00000008 */ #define DMA_CCR_TEIE DMA_CCR_TEIE_Msk /*!< Transfer error interrupt enable */ #define DMA_CCR_DIR_Pos (4U) #define DMA_CCR_DIR_Msk (0x1UL << DMA_CCR_DIR_Pos) /*!< 0x00000010 */ #define DMA_CCR_DIR DMA_CCR_DIR_Msk /*!< Data transfer direction */ #define DMA_CCR_CIRC_Pos (5U) #define DMA_CCR_CIRC_Msk (0x1UL << DMA_CCR_CIRC_Pos) /*!< 0x00000020 */ #define DMA_CCR_CIRC DMA_CCR_CIRC_Msk /*!< Circular mode */ #define DMA_CCR_PINC_Pos (6U) #define DMA_CCR_PINC_Msk (0x1UL << DMA_CCR_PINC_Pos) /*!< 0x00000040 */ #define DMA_CCR_PINC DMA_CCR_PINC_Msk /*!< Peripheral increment mode */ #define DMA_CCR_MINC_Pos (7U) #define DMA_CCR_MINC_Msk (0x1UL << DMA_CCR_MINC_Pos) /*!< 0x00000080 */ #define DMA_CCR_MINC DMA_CCR_MINC_Msk /*!< Memory increment mode */ #define DMA_CCR_PSIZE_Pos (8U) #define DMA_CCR_PSIZE_Msk (0x3UL << DMA_CCR_PSIZE_Pos) /*!< 0x00000300 */ #define DMA_CCR_PSIZE DMA_CCR_PSIZE_Msk /*!< PSIZE[1:0] bits (Peripheral size) */ #define DMA_CCR_PSIZE_0 (0x1UL << DMA_CCR_PSIZE_Pos) /*!< 0x00000100 */ #define DMA_CCR_PSIZE_1 (0x2UL << DMA_CCR_PSIZE_Pos) /*!< 0x00000200 */ #define DMA_CCR_MSIZE_Pos (10U) #define DMA_CCR_MSIZE_Msk (0x3UL << DMA_CCR_MSIZE_Pos) /*!< 0x00000C00 */ #define DMA_CCR_MSIZE DMA_CCR_MSIZE_Msk /*!< MSIZE[1:0] bits (Memory size) */ #define DMA_CCR_MSIZE_0 (0x1UL << DMA_CCR_MSIZE_Pos) /*!< 0x00000400 */ #define DMA_CCR_MSIZE_1 (0x2UL << DMA_CCR_MSIZE_Pos) /*!< 0x00000800 */ #define DMA_CCR_PL_Pos (12U) #define DMA_CCR_PL_Msk (0x3UL << DMA_CCR_PL_Pos) /*!< 0x00003000 */ #define DMA_CCR_PL DMA_CCR_PL_Msk /*!< PL[1:0] bits(Channel Priority level)*/ #define DMA_CCR_PL_0 (0x1UL << DMA_CCR_PL_Pos) /*!< 0x00001000 */ #define DMA_CCR_PL_1 (0x2UL << DMA_CCR_PL_Pos) /*!< 0x00002000 */ #define DMA_CCR_MEM2MEM_Pos (14U) #define DMA_CCR_MEM2MEM_Msk (0x1UL << DMA_CCR_MEM2MEM_Pos) /*!< 0x00004000 */ #define DMA_CCR_MEM2MEM DMA_CCR_MEM2MEM_Msk /*!< Memory to memory mode */ /****************** Bit definition for DMA_CNDTR register *******************/ #define DMA_CNDTR_NDT_Pos (0U) #define DMA_CNDTR_NDT_Msk (0xFFFFUL << DMA_CNDTR_NDT_Pos) /*!< 0x0000FFFF */ #define DMA_CNDTR_NDT DMA_CNDTR_NDT_Msk /*!< Number of data to Transfer */ /****************** Bit definition for DMA_CPAR register ********************/ #define DMA_CPAR_PA_Pos (0U) #define DMA_CPAR_PA_Msk (0xFFFFFFFFUL << DMA_CPAR_PA_Pos) /*!< 0xFFFFFFFF */ #define DMA_CPAR_PA DMA_CPAR_PA_Msk /*!< Peripheral Address */ /****************** Bit definition for DMA_CMAR register ********************/ #define DMA_CMAR_MA_Pos (0U) #define DMA_CMAR_MA_Msk (0xFFFFFFFFUL << DMA_CMAR_MA_Pos) /*!< 0xFFFFFFFF */ #define DMA_CMAR_MA DMA_CMAR_MA_Msk /*!< Memory Address */ /******************************************************************************/ /* */ /* DMAMUX Controller */ /* */ /******************************************************************************/ /******************** Bits definition for DMAMUX_CxCR register **************/ #define DMAMUX_CxCR_DMAREQ_ID_Pos (0U) #define DMAMUX_CxCR_DMAREQ_ID_Msk (0xFFUL << DMAMUX_CxCR_DMAREQ_ID_Pos) /*!< 0x000000FF */ #define DMAMUX_CxCR_DMAREQ_ID DMAMUX_CxCR_DMAREQ_ID_Msk /*!< DMA Request ID */ #define DMAMUX_CxCR_DMAREQ_ID_0 (0x01UL << DMAMUX_CxCR_DMAREQ_ID_Pos) /*!< 0x00000001 */ #define DMAMUX_CxCR_DMAREQ_ID_1 (0x02UL << DMAMUX_CxCR_DMAREQ_ID_Pos) /*!< 0x00000002 */ #define DMAMUX_CxCR_DMAREQ_ID_2 (0x04UL << DMAMUX_CxCR_DMAREQ_ID_Pos) /*!< 0x00000004 */ #define DMAMUX_CxCR_DMAREQ_ID_3 (0x08UL << DMAMUX_CxCR_DMAREQ_ID_Pos) /*!< 0x00000008 */ #define DMAMUX_CxCR_DMAREQ_ID_4 (0x10UL << DMAMUX_CxCR_DMAREQ_ID_Pos) /*!< 0x00000010 */ #define DMAMUX_CxCR_DMAREQ_ID_5 (0x20UL << DMAMUX_CxCR_DMAREQ_ID_Pos) /*!< 0x00000020 */ #define DMAMUX_CxCR_DMAREQ_ID_6 (0x40UL << DMAMUX_CxCR_DMAREQ_ID_Pos) /*!< 0x00000040 */ #define DMAMUX_CxCR_DMAREQ_ID_7 (0x80UL << DMAMUX_CxCR_DMAREQ_ID_Pos) /*!< 0x00000080 */ #define DMAMUX_CxCR_SOIE_Pos (8U) #define DMAMUX_CxCR_SOIE_Msk (0x1UL << DMAMUX_CxCR_SOIE_Pos) /*!< 0x00000100 */ #define DMAMUX_CxCR_SOIE DMAMUX_CxCR_SOIE_Msk /*!< Synchro overrun interrupt enable */ #define DMAMUX_CxCR_EGE_Pos (9U) #define DMAMUX_CxCR_EGE_Msk (0x1UL << DMAMUX_CxCR_EGE_Pos) /*!< 0x00000200 */ #define DMAMUX_CxCR_EGE DMAMUX_CxCR_EGE_Msk /*!< Event generation interrupt enable */ #define DMAMUX_CxCR_SE_Pos (16U) #define DMAMUX_CxCR_SE_Msk (0x1UL << DMAMUX_CxCR_SE_Pos) /*!< 0x00010000 */ #define DMAMUX_CxCR_SE DMAMUX_CxCR_SE_Msk /*!< Synchronization enable */ #define DMAMUX_CxCR_SPOL_Pos (17U) #define DMAMUX_CxCR_SPOL_Msk (0x3UL << DMAMUX_CxCR_SPOL_Pos) /*!< 0x00060000 */ #define DMAMUX_CxCR_SPOL DMAMUX_CxCR_SPOL_Msk /*!< Synchronization polarity */ #define DMAMUX_CxCR_SPOL_0 (0x1UL << DMAMUX_CxCR_SPOL_Pos) /*!< 0x00020000 */ #define DMAMUX_CxCR_SPOL_1 (0x2UL << DMAMUX_CxCR_SPOL_Pos) /*!< 0x00040000 */ #define DMAMUX_CxCR_NBREQ_Pos (19U) #define DMAMUX_CxCR_NBREQ_Msk (0x1FUL << DMAMUX_CxCR_NBREQ_Pos) /*!< 0x00F80000 */ #define DMAMUX_CxCR_NBREQ DMAMUX_CxCR_NBREQ_Msk /*!< Number of request */ #define DMAMUX_CxCR_NBREQ_0 (0x01UL << DMAMUX_CxCR_NBREQ_Pos) /*!< 0x00080000 */ #define DMAMUX_CxCR_NBREQ_1 (0x02UL << DMAMUX_CxCR_NBREQ_Pos) /*!< 0x00100000 */ #define DMAMUX_CxCR_NBREQ_2 (0x04UL << DMAMUX_CxCR_NBREQ_Pos) /*!< 0x00200000 */ #define DMAMUX_CxCR_NBREQ_3 (0x08UL << DMAMUX_CxCR_NBREQ_Pos) /*!< 0x00400000 */ #define DMAMUX_CxCR_NBREQ_4 (0x10UL << DMAMUX_CxCR_NBREQ_Pos) /*!< 0x00800000 */ #define DMAMUX_CxCR_SYNC_ID_Pos (24U) #define DMAMUX_CxCR_SYNC_ID_Msk (0x1FUL << DMAMUX_CxCR_SYNC_ID_Pos) /*!< 0x1F000000 */ #define DMAMUX_CxCR_SYNC_ID DMAMUX_CxCR_SYNC_ID_Msk /*!< Synchronization ID */ #define DMAMUX_CxCR_SYNC_ID_0 (0x01UL << DMAMUX_CxCR_SYNC_ID_Pos) /*!< 0x01000000 */ #define DMAMUX_CxCR_SYNC_ID_1 (0x02UL << DMAMUX_CxCR_SYNC_ID_Pos) /*!< 0x02000000 */ #define DMAMUX_CxCR_SYNC_ID_2 (0x04UL << DMAMUX_CxCR_SYNC_ID_Pos) /*!< 0x04000000 */ #define DMAMUX_CxCR_SYNC_ID_3 (0x08UL << DMAMUX_CxCR_SYNC_ID_Pos) /*!< 0x08000000 */ #define DMAMUX_CxCR_SYNC_ID_4 (0x10UL << DMAMUX_CxCR_SYNC_ID_Pos) /*!< 0x10000000 */ /******************* Bits definition for DMAMUX_CSR register **************/ #define DMAMUX_CSR_SOF0_Pos (0U) #define DMAMUX_CSR_SOF0_Msk (0x1UL << DMAMUX_CSR_SOF0_Pos) /*!< 0x00000001 */ #define DMAMUX_CSR_SOF0 DMAMUX_CSR_SOF0_Msk /*!< Synchronization Overrun Flag 0 */ #define DMAMUX_CSR_SOF1_Pos (1U) #define DMAMUX_CSR_SOF1_Msk (0x1UL << DMAMUX_CSR_SOF1_Pos) /*!< 0x00000002 */ #define DMAMUX_CSR_SOF1 DMAMUX_CSR_SOF1_Msk /*!< Synchronization Overrun Flag 1 */ #define DMAMUX_CSR_SOF2_Pos (2U) #define DMAMUX_CSR_SOF2_Msk (0x1UL << DMAMUX_CSR_SOF2_Pos) /*!< 0x00000004 */ #define DMAMUX_CSR_SOF2 DMAMUX_CSR_SOF2_Msk /*!< Synchronization Overrun Flag 2 */ /******************** Bits definition for DMAMUX_CFR register **************/ #define DMAMUX_CFR_CSOF0_Pos (0U) #define DMAMUX_CFR_CSOF0_Msk (0x1UL << DMAMUX_CFR_CSOF0_Pos) /*!< 0x00000001 */ #define DMAMUX_CFR_CSOF0 DMAMUX_CFR_CSOF0_Msk /*!< Clear Overrun Flag 0 */ #define DMAMUX_CFR_CSOF1_Pos (1U) #define DMAMUX_CFR_CSOF1_Msk (0x1UL << DMAMUX_CFR_CSOF1_Pos) /*!< 0x00000002 */ #define DMAMUX_CFR_CSOF1 DMAMUX_CFR_CSOF1_Msk /*!< Clear Overrun Flag 1 */ #define DMAMUX_CFR_CSOF2_Pos (2U) #define DMAMUX_CFR_CSOF2_Msk (0x1UL << DMAMUX_CFR_CSOF2_Pos) /*!< 0x00000004 */ #define DMAMUX_CFR_CSOF2 DMAMUX_CFR_CSOF2_Msk /*!< Clear Overrun Flag 2 */ /******************** Bits definition for DMAMUX_RGxCR register ************/ #define DMAMUX_RGxCR_SIG_ID_Pos (0U) #define DMAMUX_RGxCR_SIG_ID_Msk (0x1FUL << DMAMUX_RGxCR_SIG_ID_Pos) /*!< 0x0000001F */ #define DMAMUX_RGxCR_SIG_ID DMAMUX_RGxCR_SIG_ID_Msk /*!< Signal ID */ #define DMAMUX_RGxCR_SIG_ID_0 (0x01UL << DMAMUX_RGxCR_SIG_ID_Pos) /*!< 0x00000001 */ #define DMAMUX_RGxCR_SIG_ID_1 (0x02UL << DMAMUX_RGxCR_SIG_ID_Pos) /*!< 0x00000002 */ #define DMAMUX_RGxCR_SIG_ID_2 (0x04UL << DMAMUX_RGxCR_SIG_ID_Pos) /*!< 0x00000004 */ #define DMAMUX_RGxCR_SIG_ID_3 (0x08UL << DMAMUX_RGxCR_SIG_ID_Pos) /*!< 0x00000008 */ #define DMAMUX_RGxCR_SIG_ID_4 (0x10UL << DMAMUX_RGxCR_SIG_ID_Pos) /*!< 0x00000010 */ #define DMAMUX_RGxCR_OIE_Pos (8U) #define DMAMUX_RGxCR_OIE_Msk (0x1UL << DMAMUX_RGxCR_OIE_Pos) /*!< 0x00000100 */ #define DMAMUX_RGxCR_OIE DMAMUX_RGxCR_OIE_Msk /*!< Overrun interrupt enable */ #define DMAMUX_RGxCR_GE_Pos (16U) #define DMAMUX_RGxCR_GE_Msk (0x1UL << DMAMUX_RGxCR_GE_Pos) /*!< 0x00010000 */ #define DMAMUX_RGxCR_GE DMAMUX_RGxCR_GE_Msk /*!< Generation enable */ #define DMAMUX_RGxCR_GPOL_Pos (17U) #define DMAMUX_RGxCR_GPOL_Msk (0x3UL << DMAMUX_RGxCR_GPOL_Pos) /*!< 0x00060000 */ #define DMAMUX_RGxCR_GPOL DMAMUX_RGxCR_GPOL_Msk /*!< Generation polarity */ #define DMAMUX_RGxCR_GPOL_0 (0x1UL << DMAMUX_RGxCR_GPOL_Pos) /*!< 0x00020000 */ #define DMAMUX_RGxCR_GPOL_1 (0x2UL << DMAMUX_RGxCR_GPOL_Pos) /*!< 0x00040000 */ #define DMAMUX_RGxCR_GNBREQ_Pos (19U) #define DMAMUX_RGxCR_GNBREQ_Msk (0x1FUL << DMAMUX_RGxCR_GNBREQ_Pos) /*!< 0x00F80000 */ #define DMAMUX_RGxCR_GNBREQ DMAMUX_RGxCR_GNBREQ_Msk /*!< Number of request */ #define DMAMUX_RGxCR_GNBREQ_0 (0x01UL << DMAMUX_RGxCR_GNBREQ_Pos) /*!< 0x00080000 */ #define DMAMUX_RGxCR_GNBREQ_1 (0x02UL << DMAMUX_RGxCR_GNBREQ_Pos) /*!< 0x00100000 */ #define DMAMUX_RGxCR_GNBREQ_2 (0x04UL << DMAMUX_RGxCR_GNBREQ_Pos) /*!< 0x00200000 */ #define DMAMUX_RGxCR_GNBREQ_3 (0x08UL << DMAMUX_RGxCR_GNBREQ_Pos) /*!< 0x00400000 */ #define DMAMUX_RGxCR_GNBREQ_4 (0x10UL << DMAMUX_RGxCR_GNBREQ_Pos) /*!< 0x00800000 */ /******************** Bits definition for DMAMUX_RGSR register **************/ #define DMAMUX_RGSR_OF0_Pos (0U) #define DMAMUX_RGSR_OF0_Msk (0x1UL << DMAMUX_RGSR_OF0_Pos) /*!< 0x00000001 */ #define DMAMUX_RGSR_OF0 DMAMUX_RGSR_OF0_Msk /*!< Overrun flag 0 */ #define DMAMUX_RGSR_OF1_Pos (1U) #define DMAMUX_RGSR_OF1_Msk (0x1UL << DMAMUX_RGSR_OF1_Pos) /*!< 0x00000002 */ #define DMAMUX_RGSR_OF1 DMAMUX_RGSR_OF1_Msk /*!< Overrun flag 1 */ #define DMAMUX_RGSR_OF2_Pos (2U) #define DMAMUX_RGSR_OF2_Msk (0x1UL << DMAMUX_RGSR_OF2_Pos) /*!< 0x00000004 */ #define DMAMUX_RGSR_OF2 DMAMUX_RGSR_OF2_Msk /*!< Overrun flag 2 */ #define DMAMUX_RGSR_OF3_Pos (3U) #define DMAMUX_RGSR_OF3_Msk (0x1UL << DMAMUX_RGSR_OF3_Pos) /*!< 0x00000008 */ #define DMAMUX_RGSR_OF3 DMAMUX_RGSR_OF3_Msk /*!< Overrun flag 3 */ /******************** Bits definition for DMAMUX_RGCFR register **************/ #define DMAMUX_RGCFR_COF0_Pos (0U) #define DMAMUX_RGCFR_COF0_Msk (0x1UL << DMAMUX_RGCFR_COF0_Pos) /*!< 0x00000001 */ #define DMAMUX_RGCFR_COF0 DMAMUX_RGCFR_COF0_Msk /*!< Clear Overrun flag 0 */ #define DMAMUX_RGCFR_COF1_Pos (1U) #define DMAMUX_RGCFR_COF1_Msk (0x1UL << DMAMUX_RGCFR_COF1_Pos) /*!< 0x00000002 */ #define DMAMUX_RGCFR_COF1 DMAMUX_RGCFR_COF1_Msk /*!< Clear Overrun flag 1 */ #define DMAMUX_RGCFR_COF2_Pos (2U) #define DMAMUX_RGCFR_COF2_Msk (0x1UL << DMAMUX_RGCFR_COF2_Pos) /*!< 0x00000004 */ #define DMAMUX_RGCFR_COF2 DMAMUX_RGCFR_COF2_Msk /*!< Clear Overrun flag 2 */ #define DMAMUX_RGCFR_COF3_Pos (3U) #define DMAMUX_RGCFR_COF3_Msk (0x1UL << DMAMUX_RGCFR_COF3_Pos) /*!< 0x00000008 */ #define DMAMUX_RGCFR_COF3 DMAMUX_RGCFR_COF3_Msk /*!< Clear Overrun flag 3 */ /***************** Bits definition for DMAMUX_IPHW_CFGR2 register ************/ #define DMAMUX_IPHW_CFGR2_NB_EXT_REQ_Pos (0U) #define DMAMUX_IPHW_CFGR2_NB_EXT_REQ_Msk (0xFFUL << DMAMUX_IPHW_CFGR2_NB_EXT_REQ_Pos) /*!< 0x000000FF */ #define DMAMUX_IPHW_CFGR2_NB_EXT_REQ DMAMUX_IPHW_CFGR2_NB_EXT_REQ_Msk /*!< Number of external request sources */ /***************** Bits definition for DMAMUX_IPHW_CFGR1 register ************/ #define DMAMUX_IPHW_CFGR1_NB_STREAMS_Pos (0U) #define DMAMUX_IPHW_CFGR1_NB_STREAMS_Msk (0xFFUL << DMAMUX_IPHW_CFGR1_NB_STREAMS_Pos) /*!< 0x000000FF */ #define DMAMUX_IPHW_CFGR1_NB_STREAMS DMAMUX_IPHW_CFGR1_NB_STREAMS_Msk /*!< Number of DMA streams */ #define DMAMUX_IPHW_CFGR1_NB_PERIPH_REQ_Pos (8U) #define DMAMUX_IPHW_CFGR1_NB_PERIPH_REQ_Msk (0xFFUL << DMAMUX_IPHW_CFGR1_NB_PERIPH_REQ_Pos) /*!< 0x0000FF00 */ #define DMAMUX_IPHW_CFGR1_NB_PERIPH_REQ DMAMUX_IPHW_CFGR1_NB_PERIPH_REQ_Msk /*!< Number of peripheral requests */ #define DMAMUX_IPHW_CFGR1_NB_SYNC_TRIG_Pos (16U) #define DMAMUX_IPHW_CFGR1_NB_SYNC_TRIG_Msk (0xFFUL << DMAMUX_IPHW_CFGR1_NB_SYNC_TRIG_Pos) /*!< 0x00FF0000 */ #define DMAMUX_IPHW_CFGR1_NB_SYNC_TRIG DMAMUX_IPHW_CFGR1_NB_SYNC_TRIG_Msk /*!< Number of synchronization triggers */ #define DMAMUX_IPHW_CFGR1_NB_REQ_GEN_Pos (24U) #define DMAMUX_IPHW_CFGR1_NB_REQ_GEN_Msk (0xFFUL << DMAMUX_IPHW_CFGR1_NB_REQ_GEN_Pos) /*!< 0xFF000000 */ #define DMAMUX_IPHW_CFGR1_NB_REQ_GEN DMAMUX_IPHW_CFGR1_NB_REQ_GEN_Msk /*!< Number of request generation blocks */ /******************************************************************************/ /* */ /* External Interrupt/Event Controller */ /* */ /******************************************************************************/ /****************** Bit definition for EXTI_RTSR1 register ******************/ #define EXTI_RTSR1_RT0_Pos (0U) #define EXTI_RTSR1_RT0_Msk (0x1UL << EXTI_RTSR1_RT0_Pos) /*!< 0x00000001 */ #define EXTI_RTSR1_RT0 EXTI_RTSR1_RT0_Msk /*!< Rising trigger configuration for input line 0 */ #define EXTI_RTSR1_RT1_Pos (1U) #define EXTI_RTSR1_RT1_Msk (0x1UL << EXTI_RTSR1_RT1_Pos) /*!< 0x00000002 */ #define EXTI_RTSR1_RT1 EXTI_RTSR1_RT1_Msk /*!< Rising trigger configuration for input line 1 */ #define EXTI_RTSR1_RT2_Pos (2U) #define EXTI_RTSR1_RT2_Msk (0x1UL << EXTI_RTSR1_RT2_Pos) /*!< 0x00000004 */ #define EXTI_RTSR1_RT2 EXTI_RTSR1_RT2_Msk /*!< Rising trigger configuration for input line 2 */ #define EXTI_RTSR1_RT3_Pos (3U) #define EXTI_RTSR1_RT3_Msk (0x1UL << EXTI_RTSR1_RT3_Pos) /*!< 0x00000008 */ #define EXTI_RTSR1_RT3 EXTI_RTSR1_RT3_Msk /*!< Rising trigger configuration for input line 3 */ #define EXTI_RTSR1_RT4_Pos (4U) #define EXTI_RTSR1_RT4_Msk (0x1UL << EXTI_RTSR1_RT4_Pos) /*!< 0x00000010 */ #define EXTI_RTSR1_RT4 EXTI_RTSR1_RT4_Msk /*!< Rising trigger configuration for input line 4 */ #define EXTI_RTSR1_RT5_Pos (5U) #define EXTI_RTSR1_RT5_Msk (0x1UL << EXTI_RTSR1_RT5_Pos) /*!< 0x00000020 */ #define EXTI_RTSR1_RT5 EXTI_RTSR1_RT5_Msk /*!< Rising trigger configuration for input line 5 */ #define EXTI_RTSR1_RT6_Pos (6U) #define EXTI_RTSR1_RT6_Msk (0x1UL << EXTI_RTSR1_RT6_Pos) /*!< 0x00000040 */ #define EXTI_RTSR1_RT6 EXTI_RTSR1_RT6_Msk /*!< Rising trigger configuration for input line 6 */ #define EXTI_RTSR1_RT7_Pos (7U) #define EXTI_RTSR1_RT7_Msk (0x1UL << EXTI_RTSR1_RT7_Pos) /*!< 0x00000080 */ #define EXTI_RTSR1_RT7 EXTI_RTSR1_RT7_Msk /*!< Rising trigger configuration for input line 7 */ #define EXTI_RTSR1_RT8_Pos (8U) #define EXTI_RTSR1_RT8_Msk (0x1UL << EXTI_RTSR1_RT8_Pos) /*!< 0x00000100 */ #define EXTI_RTSR1_RT8 EXTI_RTSR1_RT8_Msk /*!< Rising trigger configuration for input line 8 */ #define EXTI_RTSR1_RT9_Pos (9U) #define EXTI_RTSR1_RT9_Msk (0x1UL << EXTI_RTSR1_RT9_Pos) /*!< 0x00000200 */ #define EXTI_RTSR1_RT9 EXTI_RTSR1_RT9_Msk /*!< Rising trigger configuration for input line 9 */ #define EXTI_RTSR1_RT10_Pos (10U) #define EXTI_RTSR1_RT10_Msk (0x1UL << EXTI_RTSR1_RT10_Pos) /*!< 0x00000400 */ #define EXTI_RTSR1_RT10 EXTI_RTSR1_RT10_Msk /*!< Rising trigger configuration for input line 10 */ #define EXTI_RTSR1_RT11_Pos (11U) #define EXTI_RTSR1_RT11_Msk (0x1UL << EXTI_RTSR1_RT11_Pos) /*!< 0x00000800 */ #define EXTI_RTSR1_RT11 EXTI_RTSR1_RT11_Msk /*!< Rising trigger configuration for input line 11 */ #define EXTI_RTSR1_RT12_Pos (12U) #define EXTI_RTSR1_RT12_Msk (0x1UL << EXTI_RTSR1_RT12_Pos) /*!< 0x00001000 */ #define EXTI_RTSR1_RT12 EXTI_RTSR1_RT12_Msk /*!< Rising trigger configuration for input line 12 */ #define EXTI_RTSR1_RT13_Pos (13U) #define EXTI_RTSR1_RT13_Msk (0x1UL << EXTI_RTSR1_RT13_Pos) /*!< 0x00002000 */ #define EXTI_RTSR1_RT13 EXTI_RTSR1_RT13_Msk /*!< Rising trigger configuration for input line 13 */ #define EXTI_RTSR1_RT14_Pos (14U) #define EXTI_RTSR1_RT14_Msk (0x1UL << EXTI_RTSR1_RT14_Pos) /*!< 0x00004000 */ #define EXTI_RTSR1_RT14 EXTI_RTSR1_RT14_Msk /*!< Rising trigger configuration for input line 14 */ #define EXTI_RTSR1_RT15_Pos (15U) #define EXTI_RTSR1_RT15_Msk (0x1UL << EXTI_RTSR1_RT15_Pos) /*!< 0x00008000 */ #define EXTI_RTSR1_RT15 EXTI_RTSR1_RT15_Msk /*!< Rising trigger configuration for input line 15 */ /****************** Bit definition for EXTI_FTSR1 register ******************/ #define EXTI_FTSR1_FT0_Pos (0U) #define EXTI_FTSR1_FT0_Msk (0x1UL << EXTI_FTSR1_FT0_Pos) /*!< 0x00000001 */ #define EXTI_FTSR1_FT0 EXTI_FTSR1_FT0_Msk /*!< Falling trigger configuration for input line 0 */ #define EXTI_FTSR1_FT1_Pos (1U) #define EXTI_FTSR1_FT1_Msk (0x1UL << EXTI_FTSR1_FT1_Pos) /*!< 0x00000002 */ #define EXTI_FTSR1_FT1 EXTI_FTSR1_FT1_Msk /*!< Falling trigger configuration for input line 1 */ #define EXTI_FTSR1_FT2_Pos (2U) #define EXTI_FTSR1_FT2_Msk (0x1UL << EXTI_FTSR1_FT2_Pos) /*!< 0x00000004 */ #define EXTI_FTSR1_FT2 EXTI_FTSR1_FT2_Msk /*!< Falling trigger configuration for input line 2 */ #define EXTI_FTSR1_FT3_Pos (3U) #define EXTI_FTSR1_FT3_Msk (0x1UL << EXTI_FTSR1_FT3_Pos) /*!< 0x00000008 */ #define EXTI_FTSR1_FT3 EXTI_FTSR1_FT3_Msk /*!< Falling trigger configuration for input line 3 */ #define EXTI_FTSR1_FT4_Pos (4U) #define EXTI_FTSR1_FT4_Msk (0x1UL << EXTI_FTSR1_FT4_Pos) /*!< 0x00000010 */ #define EXTI_FTSR1_FT4 EXTI_FTSR1_FT4_Msk /*!< Falling trigger configuration for input line 4 */ #define EXTI_FTSR1_FT5_Pos (5U) #define EXTI_FTSR1_FT5_Msk (0x1UL << EXTI_FTSR1_FT5_Pos) /*!< 0x00000020 */ #define EXTI_FTSR1_FT5 EXTI_FTSR1_FT5_Msk /*!< Falling trigger configuration for input line 5 */ #define EXTI_FTSR1_FT6_Pos (6U) #define EXTI_FTSR1_FT6_Msk (0x1UL << EXTI_FTSR1_FT6_Pos) /*!< 0x00000040 */ #define EXTI_FTSR1_FT6 EXTI_FTSR1_FT6_Msk /*!< Falling trigger configuration for input line 6 */ #define EXTI_FTSR1_FT7_Pos (7U) #define EXTI_FTSR1_FT7_Msk (0x1UL << EXTI_FTSR1_FT7_Pos) /*!< 0x00000080 */ #define EXTI_FTSR1_FT7 EXTI_FTSR1_FT7_Msk /*!< Falling trigger configuration for input line 7 */ #define EXTI_FTSR1_FT8_Pos (8U) #define EXTI_FTSR1_FT8_Msk (0x1UL << EXTI_FTSR1_FT8_Pos) /*!< 0x00000100 */ #define EXTI_FTSR1_FT8 EXTI_FTSR1_FT8_Msk /*!< Falling trigger configuration for input line 8 */ #define EXTI_FTSR1_FT9_Pos (9U) #define EXTI_FTSR1_FT9_Msk (0x1UL << EXTI_FTSR1_FT9_Pos) /*!< 0x00000200 */ #define EXTI_FTSR1_FT9 EXTI_FTSR1_FT9_Msk /*!< Falling trigger configuration for input line 9 */ #define EXTI_FTSR1_FT10_Pos (10U) #define EXTI_FTSR1_FT10_Msk (0x1UL << EXTI_FTSR1_FT10_Pos) /*!< 0x00000400 */ #define EXTI_FTSR1_FT10 EXTI_FTSR1_FT10_Msk /*!< Falling trigger configuration for input line 10 */ #define EXTI_FTSR1_FT11_Pos (11U) #define EXTI_FTSR1_FT11_Msk (0x1UL << EXTI_FTSR1_FT11_Pos) /*!< 0x00000800 */ #define EXTI_FTSR1_FT11 EXTI_FTSR1_FT11_Msk /*!< Falling trigger configuration for input line 11 */ #define EXTI_FTSR1_FT12_Pos (12U) #define EXTI_FTSR1_FT12_Msk (0x1UL << EXTI_FTSR1_FT12_Pos) /*!< 0x00001000 */ #define EXTI_FTSR1_FT12 EXTI_FTSR1_FT12_Msk /*!< Falling trigger configuration for input line 12 */ #define EXTI_FTSR1_FT13_Pos (13U) #define EXTI_FTSR1_FT13_Msk (0x1UL << EXTI_FTSR1_FT13_Pos) /*!< 0x00002000 */ #define EXTI_FTSR1_FT13 EXTI_FTSR1_FT13_Msk /*!< Falling trigger configuration for input line 13 */ #define EXTI_FTSR1_FT14_Pos (14U) #define EXTI_FTSR1_FT14_Msk (0x1UL << EXTI_FTSR1_FT14_Pos) /*!< 0x00004000 */ #define EXTI_FTSR1_FT14 EXTI_FTSR1_FT14_Msk /*!< Falling trigger configuration for input line 14 */ #define EXTI_FTSR1_FT15_Pos (15U) #define EXTI_FTSR1_FT15_Msk (0x1UL << EXTI_FTSR1_FT15_Pos) /*!< 0x00008000 */ #define EXTI_FTSR1_FT15 EXTI_FTSR1_FT15_Msk /*!< Falling trigger configuration for input line 15 */ /****************** Bit definition for EXTI_SWIER1 register *****************/ #define EXTI_SWIER1_SWI0_Pos (0U) #define EXTI_SWIER1_SWI0_Msk (0x1UL << EXTI_SWIER1_SWI0_Pos) /*!< 0x00000001 */ #define EXTI_SWIER1_SWI0 EXTI_SWIER1_SWI0_Msk /*!< Software Interrupt on line 0 */ #define EXTI_SWIER1_SWI1_Pos (1U) #define EXTI_SWIER1_SWI1_Msk (0x1UL << EXTI_SWIER1_SWI1_Pos) /*!< 0x00000002 */ #define EXTI_SWIER1_SWI1 EXTI_SWIER1_SWI1_Msk /*!< Software Interrupt on line 1 */ #define EXTI_SWIER1_SWI2_Pos (2U) #define EXTI_SWIER1_SWI2_Msk (0x1UL << EXTI_SWIER1_SWI2_Pos) /*!< 0x00000004 */ #define EXTI_SWIER1_SWI2 EXTI_SWIER1_SWI2_Msk /*!< Software Interrupt on line 2 */ #define EXTI_SWIER1_SWI3_Pos (3U) #define EXTI_SWIER1_SWI3_Msk (0x1UL << EXTI_SWIER1_SWI3_Pos) /*!< 0x00000008 */ #define EXTI_SWIER1_SWI3 EXTI_SWIER1_SWI3_Msk /*!< Software Interrupt on line 3 */ #define EXTI_SWIER1_SWI4_Pos (4U) #define EXTI_SWIER1_SWI4_Msk (0x1UL << EXTI_SWIER1_SWI4_Pos) /*!< 0x00000010 */ #define EXTI_SWIER1_SWI4 EXTI_SWIER1_SWI4_Msk /*!< Software Interrupt on line 4 */ #define EXTI_SWIER1_SWI5_Pos (5U) #define EXTI_SWIER1_SWI5_Msk (0x1UL << EXTI_SWIER1_SWI5_Pos) /*!< 0x00000020 */ #define EXTI_SWIER1_SWI5 EXTI_SWIER1_SWI5_Msk /*!< Software Interrupt on line 5 */ #define EXTI_SWIER1_SWI6_Pos (6U) #define EXTI_SWIER1_SWI6_Msk (0x1UL << EXTI_SWIER1_SWI6_Pos) /*!< 0x00000040 */ #define EXTI_SWIER1_SWI6 EXTI_SWIER1_SWI6_Msk /*!< Software Interrupt on line 6 */ #define EXTI_SWIER1_SWI7_Pos (7U) #define EXTI_SWIER1_SWI7_Msk (0x1UL << EXTI_SWIER1_SWI7_Pos) /*!< 0x00000080 */ #define EXTI_SWIER1_SWI7 EXTI_SWIER1_SWI7_Msk /*!< Software Interrupt on line 7 */ #define EXTI_SWIER1_SWI8_Pos (8U) #define EXTI_SWIER1_SWI8_Msk (0x1UL << EXTI_SWIER1_SWI8_Pos) /*!< 0x00000100 */ #define EXTI_SWIER1_SWI8 EXTI_SWIER1_SWI8_Msk /*!< Software Interrupt on line 8 */ #define EXTI_SWIER1_SWI9_Pos (9U) #define EXTI_SWIER1_SWI9_Msk (0x1UL << EXTI_SWIER1_SWI9_Pos) /*!< 0x00000200 */ #define EXTI_SWIER1_SWI9 EXTI_SWIER1_SWI9_Msk /*!< Software Interrupt on line 9 */ #define EXTI_SWIER1_SWI10_Pos (10U) #define EXTI_SWIER1_SWI10_Msk (0x1UL << EXTI_SWIER1_SWI10_Pos) /*!< 0x00000400 */ #define EXTI_SWIER1_SWI10 EXTI_SWIER1_SWI10_Msk /*!< Software Interrupt on line 10 */ #define EXTI_SWIER1_SWI11_Pos (11U) #define EXTI_SWIER1_SWI11_Msk (0x1UL << EXTI_SWIER1_SWI11_Pos) /*!< 0x00000800 */ #define EXTI_SWIER1_SWI11 EXTI_SWIER1_SWI11_Msk /*!< Software Interrupt on line 11 */ #define EXTI_SWIER1_SWI12_Pos (12U) #define EXTI_SWIER1_SWI12_Msk (0x1UL << EXTI_SWIER1_SWI12_Pos) /*!< 0x00001000 */ #define EXTI_SWIER1_SWI12 EXTI_SWIER1_SWI12_Msk /*!< Software Interrupt on line 12 */ #define EXTI_SWIER1_SWI13_Pos (13U) #define EXTI_SWIER1_SWI13_Msk (0x1UL << EXTI_SWIER1_SWI13_Pos) /*!< 0x00002000 */ #define EXTI_SWIER1_SWI13 EXTI_SWIER1_SWI13_Msk /*!< Software Interrupt on line 13 */ #define EXTI_SWIER1_SWI14_Pos (14U) #define EXTI_SWIER1_SWI14_Msk (0x1UL << EXTI_SWIER1_SWI14_Pos) /*!< 0x00004000 */ #define EXTI_SWIER1_SWI14 EXTI_SWIER1_SWI14_Msk /*!< Software Interrupt on line 14 */ #define EXTI_SWIER1_SWI15_Pos (15U) #define EXTI_SWIER1_SWI15_Msk (0x1UL << EXTI_SWIER1_SWI15_Pos) /*!< 0x00008000 */ #define EXTI_SWIER1_SWI15 EXTI_SWIER1_SWI15_Msk /*!< Software Interrupt on line 15 */ /******************* Bit definition for EXTI_RPR1 register ******************/ #define EXTI_RPR1_RPIF0_Pos (0U) #define EXTI_RPR1_RPIF0_Msk (0x1UL << EXTI_RPR1_RPIF0_Pos) /*!< 0x00000001 */ #define EXTI_RPR1_RPIF0 EXTI_RPR1_RPIF0_Msk /*!< Rising Pending Interrupt Flag on line 0 */ #define EXTI_RPR1_RPIF1_Pos (1U) #define EXTI_RPR1_RPIF1_Msk (0x1UL << EXTI_RPR1_RPIF1_Pos) /*!< 0x00000002 */ #define EXTI_RPR1_RPIF1 EXTI_RPR1_RPIF1_Msk /*!< Rising Pending Interrupt Flag on line 1 */ #define EXTI_RPR1_RPIF2_Pos (2U) #define EXTI_RPR1_RPIF2_Msk (0x1UL << EXTI_RPR1_RPIF2_Pos) /*!< 0x00000004 */ #define EXTI_RPR1_RPIF2 EXTI_RPR1_RPIF2_Msk /*!< Rising Pending Interrupt Flag on line 2 */ #define EXTI_RPR1_RPIF3_Pos (3U) #define EXTI_RPR1_RPIF3_Msk (0x1UL << EXTI_RPR1_RPIF3_Pos) /*!< 0x00000008 */ #define EXTI_RPR1_RPIF3 EXTI_RPR1_RPIF3_Msk /*!< Rising Pending Interrupt Flag on line 3 */ #define EXTI_RPR1_RPIF4_Pos (4U) #define EXTI_RPR1_RPIF4_Msk (0x1UL << EXTI_RPR1_RPIF4_Pos) /*!< 0x00000010 */ #define EXTI_RPR1_RPIF4 EXTI_RPR1_RPIF4_Msk /*!< Rising Pending Interrupt Flag on line 4 */ #define EXTI_RPR1_RPIF5_Pos (5U) #define EXTI_RPR1_RPIF5_Msk (0x1UL << EXTI_RPR1_RPIF5_Pos) /*!< 0x00000020 */ #define EXTI_RPR1_RPIF5 EXTI_RPR1_RPIF5_Msk /*!< Rising Pending Interrupt Flag on line 5 */ #define EXTI_RPR1_RPIF6_Pos (6U) #define EXTI_RPR1_RPIF6_Msk (0x1UL << EXTI_RPR1_RPIF6_Pos) /*!< 0x00000040 */ #define EXTI_RPR1_RPIF6 EXTI_RPR1_RPIF6_Msk /*!< Rising Pending Interrupt Flag on line 6 */ #define EXTI_RPR1_RPIF7_Pos (7U) #define EXTI_RPR1_RPIF7_Msk (0x1UL << EXTI_RPR1_RPIF7_Pos) /*!< 0x00000080 */ #define EXTI_RPR1_RPIF7 EXTI_RPR1_RPIF7_Msk /*!< Rising Pending Interrupt Flag on line 7 */ #define EXTI_RPR1_RPIF8_Pos (8U) #define EXTI_RPR1_RPIF8_Msk (0x1UL << EXTI_RPR1_RPIF8_Pos) /*!< 0x00000100 */ #define EXTI_RPR1_RPIF8 EXTI_RPR1_RPIF8_Msk /*!< Rising Pending Interrupt Flag on line 8 */ #define EXTI_RPR1_RPIF9_Pos (9U) #define EXTI_RPR1_RPIF9_Msk (0x1UL << EXTI_RPR1_RPIF9_Pos) /*!< 0x00000200 */ #define EXTI_RPR1_RPIF9 EXTI_RPR1_RPIF9_Msk /*!< Rising Pending Interrupt Flag on line 9 */ #define EXTI_RPR1_RPIF10_Pos (10U) #define EXTI_RPR1_RPIF10_Msk (0x1UL << EXTI_RPR1_RPIF10_Pos) /*!< 0x00000400 */ #define EXTI_RPR1_RPIF10 EXTI_RPR1_RPIF10_Msk /*!< Rising Pending Interrupt Flag on line 10 */ #define EXTI_RPR1_RPIF11_Pos (11U) #define EXTI_RPR1_RPIF11_Msk (0x1UL << EXTI_RPR1_RPIF11_Pos) /*!< 0x00000800 */ #define EXTI_RPR1_RPIF11 EXTI_RPR1_RPIF11_Msk /*!< Rising Pending Interrupt Flag on line 11 */ #define EXTI_RPR1_RPIF12_Pos (12U) #define EXTI_RPR1_RPIF12_Msk (0x1UL << EXTI_RPR1_RPIF12_Pos) /*!< 0x00001000 */ #define EXTI_RPR1_RPIF12 EXTI_RPR1_RPIF12_Msk /*!< Rising Pending Interrupt Flag on line 12 */ #define EXTI_RPR1_RPIF13_Pos (13U) #define EXTI_RPR1_RPIF13_Msk (0x1UL << EXTI_RPR1_RPIF13_Pos) /*!< 0x00002000 */ #define EXTI_RPR1_RPIF13 EXTI_RPR1_RPIF13_Msk /*!< Rising Pending Interrupt Flag on line 13 */ #define EXTI_RPR1_RPIF14_Pos (14U) #define EXTI_RPR1_RPIF14_Msk (0x1UL << EXTI_RPR1_RPIF14_Pos) /*!< 0x00004000 */ #define EXTI_RPR1_RPIF14 EXTI_RPR1_RPIF14_Msk /*!< Rising Pending Interrupt Flag on line 14 */ #define EXTI_RPR1_RPIF15_Pos (15U) #define EXTI_RPR1_RPIF15_Msk (0x1UL << EXTI_RPR1_RPIF15_Pos) /*!< 0x00008000 */ #define EXTI_RPR1_RPIF15 EXTI_RPR1_RPIF15_Msk /*!< Rising Pending Interrupt Flag on line 15 */ /******************* Bit definition for EXTI_FPR1 register ******************/ #define EXTI_FPR1_FPIF0_Pos (0U) #define EXTI_FPR1_FPIF0_Msk (0x1UL << EXTI_FPR1_FPIF0_Pos) /*!< 0x00000001 */ #define EXTI_FPR1_FPIF0 EXTI_FPR1_FPIF0_Msk /*!< Falling Pending Interrupt Flag on line 0 */ #define EXTI_FPR1_FPIF1_Pos (1U) #define EXTI_FPR1_FPIF1_Msk (0x1UL << EXTI_FPR1_FPIF1_Pos) /*!< 0x00000002 */ #define EXTI_FPR1_FPIF1 EXTI_FPR1_FPIF1_Msk /*!< Falling Pending Interrupt Flag on line 1 */ #define EXTI_FPR1_FPIF2_Pos (2U) #define EXTI_FPR1_FPIF2_Msk (0x1UL << EXTI_FPR1_FPIF2_Pos) /*!< 0x00000004 */ #define EXTI_FPR1_FPIF2 EXTI_FPR1_FPIF2_Msk /*!< Falling Pending Interrupt Flag on line 2 */ #define EXTI_FPR1_FPIF3_Pos (3U) #define EXTI_FPR1_FPIF3_Msk (0x1UL << EXTI_FPR1_FPIF3_Pos) /*!< 0x00000008 */ #define EXTI_FPR1_FPIF3 EXTI_FPR1_FPIF3_Msk /*!< Falling Pending Interrupt Flag on line 3 */ #define EXTI_FPR1_FPIF4_Pos (4U) #define EXTI_FPR1_FPIF4_Msk (0x1UL << EXTI_FPR1_FPIF4_Pos) /*!< 0x00000010 */ #define EXTI_FPR1_FPIF4 EXTI_FPR1_FPIF4_Msk /*!< Falling Pending Interrupt Flag on line 4 */ #define EXTI_FPR1_FPIF5_Pos (5U) #define EXTI_FPR1_FPIF5_Msk (0x1UL << EXTI_FPR1_FPIF5_Pos) /*!< 0x00000020 */ #define EXTI_FPR1_FPIF5 EXTI_FPR1_FPIF5_Msk /*!< Falling Pending Interrupt Flag on line 5 */ #define EXTI_FPR1_FPIF6_Pos (6U) #define EXTI_FPR1_FPIF6_Msk (0x1UL << EXTI_FPR1_FPIF6_Pos) /*!< 0x00000040 */ #define EXTI_FPR1_FPIF6 EXTI_FPR1_FPIF6_Msk /*!< Falling Pending Interrupt Flag on line 6 */ #define EXTI_FPR1_FPIF7_Pos (7U) #define EXTI_FPR1_FPIF7_Msk (0x1UL << EXTI_FPR1_FPIF7_Pos) /*!< 0x00000080 */ #define EXTI_FPR1_FPIF7 EXTI_FPR1_FPIF7_Msk /*!< Falling Pending Interrupt Flag on line 7 */ #define EXTI_FPR1_FPIF8_Pos (8U) #define EXTI_FPR1_FPIF8_Msk (0x1UL << EXTI_FPR1_FPIF8_Pos) /*!< 0x00000100 */ #define EXTI_FPR1_FPIF8 EXTI_FPR1_FPIF8_Msk /*!< Falling Pending Interrupt Flag on line 8 */ #define EXTI_FPR1_FPIF9_Pos (9U) #define EXTI_FPR1_FPIF9_Msk (0x1UL << EXTI_FPR1_FPIF9_Pos) /*!< 0x00000200 */ #define EXTI_FPR1_FPIF9 EXTI_FPR1_FPIF9_Msk /*!< Falling Pending Interrupt Flag on line 9 */ #define EXTI_FPR1_FPIF10_Pos (10U) #define EXTI_FPR1_FPIF10_Msk (0x1UL << EXTI_FPR1_FPIF10_Pos) /*!< 0x00000400 */ #define EXTI_FPR1_FPIF10 EXTI_FPR1_FPIF10_Msk /*!< Falling Pending Interrupt Flag on line 10 */ #define EXTI_FPR1_FPIF11_Pos (11U) #define EXTI_FPR1_FPIF11_Msk (0x1UL << EXTI_FPR1_FPIF11_Pos) /*!< 0x00000800 */ #define EXTI_FPR1_FPIF11 EXTI_FPR1_FPIF11_Msk /*!< Falling Pending Interrupt Flag on line 11 */ #define EXTI_FPR1_FPIF12_Pos (12U) #define EXTI_FPR1_FPIF12_Msk (0x1UL << EXTI_FPR1_FPIF12_Pos) /*!< 0x00001000 */ #define EXTI_FPR1_FPIF12 EXTI_FPR1_FPIF12_Msk /*!< Falling Pending Interrupt Flag on line 12 */ #define EXTI_FPR1_FPIF13_Pos (13U) #define EXTI_FPR1_FPIF13_Msk (0x1UL << EXTI_FPR1_FPIF13_Pos) /*!< 0x00002000 */ #define EXTI_FPR1_FPIF13 EXTI_FPR1_FPIF13_Msk /*!< Falling Pending Interrupt Flag on line 13 */ #define EXTI_FPR1_FPIF14_Pos (14U) #define EXTI_FPR1_FPIF14_Msk (0x1UL << EXTI_FPR1_FPIF14_Pos) /*!< 0x00004000 */ #define EXTI_FPR1_FPIF14 EXTI_FPR1_FPIF14_Msk /*!< Falling Pending Interrupt Flag on line 14 */ #define EXTI_FPR1_FPIF15_Pos (15U) #define EXTI_FPR1_FPIF15_Msk (0x1UL << EXTI_FPR1_FPIF15_Pos) /*!< 0x00008000 */ #define EXTI_FPR1_FPIF15 EXTI_FPR1_FPIF15_Msk /*!< Falling Pending Interrupt Flag on line 15 */ /***************** Bit definition for EXTI_EXTICR1 register **************/ #define EXTI_EXTICR1_EXTI0_Pos (0U) #define EXTI_EXTICR1_EXTI0_Msk (0x7UL << EXTI_EXTICR1_EXTI0_Pos) /*!< 0x00000007 */ #define EXTI_EXTICR1_EXTI0 EXTI_EXTICR1_EXTI0_Msk /*!< EXTI 0 configuration */ #define EXTI_EXTICR1_EXTI0_0 (0x1UL << EXTI_EXTICR1_EXTI0_Pos) /*!< 0x00000001 */ #define EXTI_EXTICR1_EXTI0_1 (0x2UL << EXTI_EXTICR1_EXTI0_Pos) /*!< 0x00000002 */ #define EXTI_EXTICR1_EXTI0_2 (0x4UL << EXTI_EXTICR1_EXTI0_Pos) /*!< 0x00000004 */ #define EXTI_EXTICR1_EXTI1_Pos (8U) #define EXTI_EXTICR1_EXTI1_Msk (0x7UL << EXTI_EXTICR1_EXTI1_Pos) /*!< 0x00000700 */ #define EXTI_EXTICR1_EXTI1 EXTI_EXTICR1_EXTI1_Msk /*!< EXTI 1 configuration */ #define EXTI_EXTICR1_EXTI1_0 (0x1UL << EXTI_EXTICR1_EXTI1_Pos) /*!< 0x00000100 */ #define EXTI_EXTICR1_EXTI1_1 (0x2UL << EXTI_EXTICR1_EXTI1_Pos) /*!< 0x00000200 */ #define EXTI_EXTICR1_EXTI1_2 (0x4UL << EXTI_EXTICR1_EXTI1_Pos) /*!< 0x00000400 */ #define EXTI_EXTICR1_EXTI2_Pos (16U) #define EXTI_EXTICR1_EXTI2_Msk (0x7UL << EXTI_EXTICR1_EXTI2_Pos) /*!< 0x00070000 */ #define EXTI_EXTICR1_EXTI2 EXTI_EXTICR1_EXTI2_Msk /*!< EXTI 2 configuration */ #define EXTI_EXTICR1_EXTI2_0 (0x1UL << EXTI_EXTICR1_EXTI2_Pos) /*!< 0x00010000 */ #define EXTI_EXTICR1_EXTI2_1 (0x2UL << EXTI_EXTICR1_EXTI2_Pos) /*!< 0x00020000 */ #define EXTI_EXTICR1_EXTI2_2 (0x4UL << EXTI_EXTICR1_EXTI2_Pos) /*!< 0x00040000 */ #define EXTI_EXTICR1_EXTI3_Pos (24U) #define EXTI_EXTICR1_EXTI3_Msk (0x7UL << EXTI_EXTICR1_EXTI3_Pos) /*!< 0x07000000 */ #define EXTI_EXTICR1_EXTI3 EXTI_EXTICR1_EXTI3_Msk /*!< EXTI 3 configuration */ #define EXTI_EXTICR1_EXTI3_0 (0x1UL << EXTI_EXTICR1_EXTI3_Pos) /*!< 0x01000000 */ #define EXTI_EXTICR1_EXTI3_1 (0x2UL << EXTI_EXTICR1_EXTI3_Pos) /*!< 0x02000000 */ #define EXTI_EXTICR1_EXTI3_2 (0x4UL << EXTI_EXTICR1_EXTI3_Pos) /*!< 0x04000000 */ /***************** Bit definition for EXTI_EXTICR2 register **************/ #define EXTI_EXTICR2_EXTI4_Pos (0U) #define EXTI_EXTICR2_EXTI4_Msk (0x7UL << EXTI_EXTICR2_EXTI4_Pos) /*!< 0x00000007 */ #define EXTI_EXTICR2_EXTI4 EXTI_EXTICR2_EXTI4_Msk /*!< EXTI 4 configuration */ #define EXTI_EXTICR2_EXTI4_0 (0x1UL << EXTI_EXTICR2_EXTI4_Pos) /*!< 0x00000001 */ #define EXTI_EXTICR2_EXTI4_1 (0x2UL << EXTI_EXTICR2_EXTI4_Pos) /*!< 0x00000002 */ #define EXTI_EXTICR2_EXTI4_2 (0x4UL << EXTI_EXTICR2_EXTI4_Pos) /*!< 0x00000004 */ #define EXTI_EXTICR2_EXTI5_Pos (8U) #define EXTI_EXTICR2_EXTI5_Msk (0x7UL << EXTI_EXTICR2_EXTI5_Pos) /*!< 0x00000700 */ #define EXTI_EXTICR2_EXTI5 EXTI_EXTICR2_EXTI5_Msk /*!< EXTI 5 configuration */ #define EXTI_EXTICR2_EXTI5_0 (0x1UL << EXTI_EXTICR2_EXTI5_Pos) /*!< 0x00000100 */ #define EXTI_EXTICR2_EXTI5_1 (0x2UL << EXTI_EXTICR2_EXTI5_Pos) /*!< 0x00000200 */ #define EXTI_EXTICR2_EXTI5_2 (0x4UL << EXTI_EXTICR2_EXTI5_Pos) /*!< 0x00000400 */ #define EXTI_EXTICR2_EXTI6_Pos (16U) #define EXTI_EXTICR2_EXTI6_Msk (0x7UL << EXTI_EXTICR2_EXTI6_Pos) /*!< 0x00070000 */ #define EXTI_EXTICR2_EXTI6 EXTI_EXTICR2_EXTI6_Msk /*!< EXTI 6 configuration */ #define EXTI_EXTICR2_EXTI6_0 (0x1UL << EXTI_EXTICR2_EXTI6_Pos) /*!< 0x00010000 */ #define EXTI_EXTICR2_EXTI6_1 (0x2UL << EXTI_EXTICR2_EXTI6_Pos) /*!< 0x00020000 */ #define EXTI_EXTICR2_EXTI6_2 (0x4UL << EXTI_EXTICR2_EXTI6_Pos) /*!< 0x00040000 */ #define EXTI_EXTICR2_EXTI7_Pos (24U) #define EXTI_EXTICR2_EXTI7_Msk (0x7UL << EXTI_EXTICR2_EXTI7_Pos) /*!< 0x07000000 */ #define EXTI_EXTICR2_EXTI7 EXTI_EXTICR2_EXTI7_Msk /*!< EXTI 7 configuration */ #define EXTI_EXTICR2_EXTI7_0 (0x1UL << EXTI_EXTICR2_EXTI7_Pos) /*!< 0x01000000 */ #define EXTI_EXTICR2_EXTI7_1 (0x2UL << EXTI_EXTICR2_EXTI7_Pos) /*!< 0x02000000 */ #define EXTI_EXTICR2_EXTI7_2 (0x4UL << EXTI_EXTICR2_EXTI7_Pos) /*!< 0x04000000 */ /***************** Bit definition for EXTI_EXTICR3 register **************/ #define EXTI_EXTICR3_EXTI8_Pos (0U) #define EXTI_EXTICR3_EXTI8_Msk (0x7UL << EXTI_EXTICR3_EXTI8_Pos) /*!< 0x00000007 */ #define EXTI_EXTICR3_EXTI8 EXTI_EXTICR3_EXTI8_Msk /*!< EXTI 8 configuration */ #define EXTI_EXTICR3_EXTI8_0 (0x1UL << EXTI_EXTICR3_EXTI8_Pos) /*!< 0x00000001 */ #define EXTI_EXTICR3_EXTI8_1 (0x2UL << EXTI_EXTICR3_EXTI8_Pos) /*!< 0x00000002 */ #define EXTI_EXTICR3_EXTI8_2 (0x4UL << EXTI_EXTICR3_EXTI8_Pos) /*!< 0x00000004 */ #define EXTI_EXTICR3_EXTI9_Pos (8U) #define EXTI_EXTICR3_EXTI9_Msk (0x7UL << EXTI_EXTICR3_EXTI9_Pos) /*!< 0x00000700 */ #define EXTI_EXTICR3_EXTI9 EXTI_EXTICR3_EXTI9_Msk /*!< EXTI 9 configuration */ #define EXTI_EXTICR3_EXTI9_0 (0x1UL << EXTI_EXTICR3_EXTI9_Pos) /*!< 0x00000100 */ #define EXTI_EXTICR3_EXTI9_1 (0x2UL << EXTI_EXTICR3_EXTI9_Pos) /*!< 0x00000200 */ #define EXTI_EXTICR3_EXTI9_2 (0x4UL << EXTI_EXTICR3_EXTI9_Pos) /*!< 0x00000400 */ #define EXTI_EXTICR3_EXTI10_Pos (16U) #define EXTI_EXTICR3_EXTI10_Msk (0x7UL << EXTI_EXTICR3_EXTI10_Pos) /*!< 0x00070000 */ #define EXTI_EXTICR3_EXTI10 EXTI_EXTICR3_EXTI10_Msk /*!< EXTI 10 configuration */ #define EXTI_EXTICR3_EXTI10_0 (0x1UL << EXTI_EXTICR3_EXTI10_Pos) /*!< 0x00010000 */ #define EXTI_EXTICR3_EXTI10_1 (0x2UL << EXTI_EXTICR3_EXTI10_Pos) /*!< 0x00020000 */ #define EXTI_EXTICR3_EXTI10_2 (0x4UL << EXTI_EXTICR3_EXTI10_Pos) /*!< 0x00040000 */ #define EXTI_EXTICR3_EXTI11_Pos (24U) #define EXTI_EXTICR3_EXTI11_Msk (0x7UL << EXTI_EXTICR3_EXTI11_Pos) /*!< 0x07000000 */ #define EXTI_EXTICR3_EXTI11 EXTI_EXTICR3_EXTI11_Msk /*!< EXTI 11 configuration */ #define EXTI_EXTICR3_EXTI11_0 (0x1UL << EXTI_EXTICR3_EXTI11_Pos) /*!< 0x01000000 */ #define EXTI_EXTICR3_EXTI11_1 (0x2UL << EXTI_EXTICR3_EXTI11_Pos) /*!< 0x02000000 */ #define EXTI_EXTICR3_EXTI11_2 (0x4UL << EXTI_EXTICR3_EXTI11_Pos) /*!< 0x04000000 */ /***************** Bit definition for EXTI_EXTICR4 register **************/ #define EXTI_EXTICR4_EXTI12_Pos (0U) #define EXTI_EXTICR4_EXTI12_Msk (0x7UL << EXTI_EXTICR4_EXTI12_Pos) /*!< 0x00000007 */ #define EXTI_EXTICR4_EXTI12 EXTI_EXTICR4_EXTI12_Msk /*!< EXTI 12 configuration */ #define EXTI_EXTICR4_EXTI12_0 (0x1UL << EXTI_EXTICR4_EXTI12_Pos) /*!< 0x00000001 */ #define EXTI_EXTICR4_EXTI12_1 (0x2UL << EXTI_EXTICR4_EXTI12_Pos) /*!< 0x00000002 */ #define EXTI_EXTICR4_EXTI12_2 (0x4UL << EXTI_EXTICR4_EXTI12_Pos) /*!< 0x00000004 */ #define EXTI_EXTICR4_EXTI13_Pos (8U) #define EXTI_EXTICR4_EXTI13_Msk (0x7UL << EXTI_EXTICR4_EXTI13_Pos) /*!< 0x00000700 */ #define EXTI_EXTICR4_EXTI13 EXTI_EXTICR4_EXTI13_Msk /*!< EXTI 13 configuration */ #define EXTI_EXTICR4_EXTI13_0 (0x1UL << EXTI_EXTICR4_EXTI13_Pos) /*!< 0x00000100 */ #define EXTI_EXTICR4_EXTI13_1 (0x2UL << EXTI_EXTICR4_EXTI13_Pos) /*!< 0x00000200 */ #define EXTI_EXTICR4_EXTI13_2 (0x4UL << EXTI_EXTICR4_EXTI13_Pos) /*!< 0x00000400 */ #define EXTI_EXTICR4_EXTI14_Pos (16U) #define EXTI_EXTICR4_EXTI14_Msk (0x7UL << EXTI_EXTICR4_EXTI14_Pos) /*!< 0x00070000 */ #define EXTI_EXTICR4_EXTI14 EXTI_EXTICR4_EXTI14_Msk /*!< EXTI 14 configuration */ #define EXTI_EXTICR4_EXTI14_0 (0x1UL << EXTI_EXTICR4_EXTI14_Pos) /*!< 0x00010000 */ #define EXTI_EXTICR4_EXTI14_1 (0x2UL << EXTI_EXTICR4_EXTI14_Pos) /*!< 0x00020000 */ #define EXTI_EXTICR4_EXTI14_2 (0x4UL << EXTI_EXTICR4_EXTI14_Pos) /*!< 0x00040000 */ #define EXTI_EXTICR4_EXTI15_Pos (24U) #define EXTI_EXTICR4_EXTI15_Msk (0x7UL << EXTI_EXTICR4_EXTI15_Pos) /*!< 0x07000000 */ #define EXTI_EXTICR4_EXTI15 EXTI_EXTICR4_EXTI15_Msk /*!< EXTI 15 configuration */ #define EXTI_EXTICR4_EXTI15_0 (0x1UL << EXTI_EXTICR4_EXTI15_Pos) /*!< 0x01000000 */ #define EXTI_EXTICR4_EXTI15_1 (0x2UL << EXTI_EXTICR4_EXTI15_Pos) /*!< 0x02000000 */ #define EXTI_EXTICR4_EXTI15_2 (0x4UL << EXTI_EXTICR4_EXTI15_Pos) /*!< 0x04000000 */ /******************* Bit definition for EXTI_IMR1 register ******************/ #define EXTI_IMR1_IM0_Pos (0U) #define EXTI_IMR1_IM0_Msk (0x1UL << EXTI_IMR1_IM0_Pos) /*!< 0x00000001 */ #define EXTI_IMR1_IM0 EXTI_IMR1_IM0_Msk /*!< Interrupt Mask on line 0 */ #define EXTI_IMR1_IM1_Pos (1U) #define EXTI_IMR1_IM1_Msk (0x1UL << EXTI_IMR1_IM1_Pos) /*!< 0x00000002 */ #define EXTI_IMR1_IM1 EXTI_IMR1_IM1_Msk /*!< Interrupt Mask on line 1 */ #define EXTI_IMR1_IM2_Pos (2U) #define EXTI_IMR1_IM2_Msk (0x1UL << EXTI_IMR1_IM2_Pos) /*!< 0x00000004 */ #define EXTI_IMR1_IM2 EXTI_IMR1_IM2_Msk /*!< Interrupt Mask on line 2 */ #define EXTI_IMR1_IM3_Pos (3U) #define EXTI_IMR1_IM3_Msk (0x1UL << EXTI_IMR1_IM3_Pos) /*!< 0x00000008 */ #define EXTI_IMR1_IM3 EXTI_IMR1_IM3_Msk /*!< Interrupt Mask on line 3 */ #define EXTI_IMR1_IM4_Pos (4U) #define EXTI_IMR1_IM4_Msk (0x1UL << EXTI_IMR1_IM4_Pos) /*!< 0x00000010 */ #define EXTI_IMR1_IM4 EXTI_IMR1_IM4_Msk /*!< Interrupt Mask on line 4 */ #define EXTI_IMR1_IM5_Pos (5U) #define EXTI_IMR1_IM5_Msk (0x1UL << EXTI_IMR1_IM5_Pos) /*!< 0x00000020 */ #define EXTI_IMR1_IM5 EXTI_IMR1_IM5_Msk /*!< Interrupt Mask on line 5 */ #define EXTI_IMR1_IM6_Pos (6U) #define EXTI_IMR1_IM6_Msk (0x1UL << EXTI_IMR1_IM6_Pos) /*!< 0x00000040 */ #define EXTI_IMR1_IM6 EXTI_IMR1_IM6_Msk /*!< Interrupt Mask on line 6 */ #define EXTI_IMR1_IM7_Pos (7U) #define EXTI_IMR1_IM7_Msk (0x1UL << EXTI_IMR1_IM7_Pos) /*!< 0x00000080 */ #define EXTI_IMR1_IM7 EXTI_IMR1_IM7_Msk /*!< Interrupt Mask on line 7 */ #define EXTI_IMR1_IM8_Pos (8U) #define EXTI_IMR1_IM8_Msk (0x1UL << EXTI_IMR1_IM8_Pos) /*!< 0x00000100 */ #define EXTI_IMR1_IM8 EXTI_IMR1_IM8_Msk /*!< Interrupt Mask on line 8 */ #define EXTI_IMR1_IM9_Pos (9U) #define EXTI_IMR1_IM9_Msk (0x1UL << EXTI_IMR1_IM9_Pos) /*!< 0x00000200 */ #define EXTI_IMR1_IM9 EXTI_IMR1_IM9_Msk /*!< Interrupt Mask on line 9 */ #define EXTI_IMR1_IM10_Pos (10U) #define EXTI_IMR1_IM10_Msk (0x1UL << EXTI_IMR1_IM10_Pos) /*!< 0x00000400 */ #define EXTI_IMR1_IM10 EXTI_IMR1_IM10_Msk /*!< Interrupt Mask on line 10 */ #define EXTI_IMR1_IM11_Pos (11U) #define EXTI_IMR1_IM11_Msk (0x1UL << EXTI_IMR1_IM11_Pos) /*!< 0x00000800 */ #define EXTI_IMR1_IM11 EXTI_IMR1_IM11_Msk /*!< Interrupt Mask on line 11 */ #define EXTI_IMR1_IM12_Pos (12U) #define EXTI_IMR1_IM12_Msk (0x1UL << EXTI_IMR1_IM12_Pos) /*!< 0x00001000 */ #define EXTI_IMR1_IM12 EXTI_IMR1_IM12_Msk /*!< Interrupt Mask on line 12 */ #define EXTI_IMR1_IM13_Pos (13U) #define EXTI_IMR1_IM13_Msk (0x1UL << EXTI_IMR1_IM13_Pos) /*!< 0x00002000 */ #define EXTI_IMR1_IM13 EXTI_IMR1_IM13_Msk /*!< Interrupt Mask on line 13 */ #define EXTI_IMR1_IM14_Pos (14U) #define EXTI_IMR1_IM14_Msk (0x1UL << EXTI_IMR1_IM14_Pos) /*!< 0x00004000 */ #define EXTI_IMR1_IM14 EXTI_IMR1_IM14_Msk /*!< Interrupt Mask on line 14 */ #define EXTI_IMR1_IM15_Pos (15U) #define EXTI_IMR1_IM15_Msk (0x1UL << EXTI_IMR1_IM15_Pos) /*!< 0x00008000 */ #define EXTI_IMR1_IM15 EXTI_IMR1_IM15_Msk /*!< Interrupt Mask on line 15 */ #define EXTI_IMR1_IM16_Pos (16U) #define EXTI_IMR1_IM16_Msk (0x1UL << EXTI_IMR1_IM16_Pos) /*!< 0x00010000 */ #define EXTI_IMR1_IM16 EXTI_IMR1_IM16_Msk /*!< Interrupt Mask on line 16 */ #define EXTI_IMR1_IM17_Pos (17U) #define EXTI_IMR1_IM17_Msk (0x1UL << EXTI_IMR1_IM17_Pos) /*!< 0x00020000 */ #define EXTI_IMR1_IM17 EXTI_IMR1_IM17_Msk /*!< Interrupt Mask on line 17 */ #define EXTI_IMR1_IM18_Pos (18U) #define EXTI_IMR1_IM18_Msk (0x1UL << EXTI_IMR1_IM18_Pos) /*!< 0x00040000 */ #define EXTI_IMR1_IM18 EXTI_IMR1_IM18_Msk /*!< Interrupt Mask on line 18 */ #define EXTI_IMR1_IM19_Pos (19U) #define EXTI_IMR1_IM19_Msk (0x1UL << EXTI_IMR1_IM19_Pos) /*!< 0x00080000 */ #define EXTI_IMR1_IM19 EXTI_IMR1_IM19_Msk /*!< Interrupt Mask on line 19 */ #define EXTI_IMR1_IM20_Pos (20U) #define EXTI_IMR1_IM20_Msk (0x1UL << EXTI_IMR1_IM20_Pos) /*!< 0x00100000 */ #define EXTI_IMR1_IM20 EXTI_IMR1_IM20_Msk /*!< Interrupt Mask on line 20 */ #define EXTI_IMR1_IM21_Pos (21U) #define EXTI_IMR1_IM21_Msk (0x1UL << EXTI_IMR1_IM21_Pos) /*!< 0x00200000 */ #define EXTI_IMR1_IM21 EXTI_IMR1_IM21_Msk /*!< Interrupt Mask on line 21 */ #define EXTI_IMR1_IM22_Pos (22U) #define EXTI_IMR1_IM22_Msk (0x1UL << EXTI_IMR1_IM22_Pos) /*!< 0x00400000 */ #define EXTI_IMR1_IM22 EXTI_IMR1_IM22_Msk /*!< Interrupt Mask on line 22 */ #define EXTI_IMR1_IM23_Pos (23U) #define EXTI_IMR1_IM23_Msk (0x1UL << EXTI_IMR1_IM23_Pos) /*!< 0x00800000 */ #define EXTI_IMR1_IM23 EXTI_IMR1_IM23_Msk /*!< Interrupt Mask on line 23 */ #define EXTI_IMR1_IM24_Pos (24U) #define EXTI_IMR1_IM24_Msk (0x1UL << EXTI_IMR1_IM24_Pos) /*!< 0x01000000 */ #define EXTI_IMR1_IM24 EXTI_IMR1_IM24_Msk /*!< Interrupt Mask on line 24 */ #define EXTI_IMR1_IM25_Pos (25U) #define EXTI_IMR1_IM25_Msk (0x1UL << EXTI_IMR1_IM25_Pos) /*!< 0x02000000 */ #define EXTI_IMR1_IM25 EXTI_IMR1_IM25_Msk /*!< Interrupt Mask on line 25 */ #define EXTI_IMR1_IM26_Pos (26U) #define EXTI_IMR1_IM26_Msk (0x1UL << EXTI_IMR1_IM26_Pos) /*!< 0x04000000 */ #define EXTI_IMR1_IM26 EXTI_IMR1_IM26_Msk /*!< Interrupt Mask on line 26 */ #define EXTI_IMR1_IM27_Pos (27U) #define EXTI_IMR1_IM27_Msk (0x1UL << EXTI_IMR1_IM27_Pos) /*!< 0x08000000 */ #define EXTI_IMR1_IM27 EXTI_IMR1_IM27_Msk /*!< Interrupt Mask on line 27 */ #define EXTI_IMR1_IM28_Pos (28U) #define EXTI_IMR1_IM28_Msk (0x1UL << EXTI_IMR1_IM28_Pos) /*!< 0x10000000 */ #define EXTI_IMR1_IM28 EXTI_IMR1_IM28_Msk /*!< Interrupt Mask on line 28 */ #define EXTI_IMR1_IM29_Pos (29U) #define EXTI_IMR1_IM29_Msk (0x1UL << EXTI_IMR1_IM29_Pos) /*!< 0x20000000 */ #define EXTI_IMR1_IM29 EXTI_IMR1_IM29_Msk /*!< Interrupt Mask on line 29 */ #define EXTI_IMR1_IM30_Pos (30U) #define EXTI_IMR1_IM30_Msk (0x1UL << EXTI_IMR1_IM30_Pos) /*!< 0x40000000 */ #define EXTI_IMR1_IM30 EXTI_IMR1_IM30_Msk /*!< Interrupt Mask on line 30 */ #define EXTI_IMR1_IM31_Pos (31U) #define EXTI_IMR1_IM31_Msk (0x1UL << EXTI_IMR1_IM31_Pos) /*!< 0x80000000 */ #define EXTI_IMR1_IM31 EXTI_IMR1_IM31_Msk /*!< Interrupt Mask on line 31 */ #define EXTI_IMR1_IM_Pos (0U) #define EXTI_IMR1_IM_Msk (0xFEAFFFFFUL << EXTI_IMR1_IM_Pos) /*!< 0xFEAFFFFF */ #define EXTI_IMR1_IM EXTI_IMR1_IM_Msk /*!< Interrupt Mask All */ /******************* Bit definition for EXTI_EMR1 register ******************/ #define EXTI_EMR1_EM0_Pos (0U) #define EXTI_EMR1_EM0_Msk (0x1UL << EXTI_EMR1_EM0_Pos) /*!< 0x00000001 */ #define EXTI_EMR1_EM0 EXTI_EMR1_EM0_Msk /*!< Event Mask on line 0 */ #define EXTI_EMR1_EM1_Pos (1U) #define EXTI_EMR1_EM1_Msk (0x1UL << EXTI_EMR1_EM1_Pos) /*!< 0x00000002 */ #define EXTI_EMR1_EM1 EXTI_EMR1_EM1_Msk /*!< Event Mask on line 1 */ #define EXTI_EMR1_EM2_Pos (2U) #define EXTI_EMR1_EM2_Msk (0x1UL << EXTI_EMR1_EM2_Pos) /*!< 0x00000004 */ #define EXTI_EMR1_EM2 EXTI_EMR1_EM2_Msk /*!< Event Mask on line 2 */ #define EXTI_EMR1_EM3_Pos (3U) #define EXTI_EMR1_EM3_Msk (0x1UL << EXTI_EMR1_EM3_Pos) /*!< 0x00000008 */ #define EXTI_EMR1_EM3 EXTI_EMR1_EM3_Msk /*!< Event Mask on line 3 */ #define EXTI_EMR1_EM4_Pos (4U) #define EXTI_EMR1_EM4_Msk (0x1UL << EXTI_EMR1_EM4_Pos) /*!< 0x00000010 */ #define EXTI_EMR1_EM4 EXTI_EMR1_EM4_Msk /*!< Event Mask on line 4 */ #define EXTI_EMR1_EM5_Pos (5U) #define EXTI_EMR1_EM5_Msk (0x1UL << EXTI_EMR1_EM5_Pos) /*!< 0x00000020 */ #define EXTI_EMR1_EM5 EXTI_EMR1_EM5_Msk /*!< Event Mask on line 5 */ #define EXTI_EMR1_EM6_Pos (6U) #define EXTI_EMR1_EM6_Msk (0x1UL << EXTI_EMR1_EM6_Pos) /*!< 0x00000040 */ #define EXTI_EMR1_EM6 EXTI_EMR1_EM6_Msk /*!< Event Mask on line 6 */ #define EXTI_EMR1_EM7_Pos (7U) #define EXTI_EMR1_EM7_Msk (0x1UL << EXTI_EMR1_EM7_Pos) /*!< 0x00000080 */ #define EXTI_EMR1_EM7 EXTI_EMR1_EM7_Msk /*!< Event Mask on line 7 */ #define EXTI_EMR1_EM8_Pos (8U) #define EXTI_EMR1_EM8_Msk (0x1UL << EXTI_EMR1_EM8_Pos) /*!< 0x00000100 */ #define EXTI_EMR1_EM8 EXTI_EMR1_EM8_Msk /*!< Event Mask on line 8 */ #define EXTI_EMR1_EM9_Pos (9U) #define EXTI_EMR1_EM9_Msk (0x1UL << EXTI_EMR1_EM9_Pos) /*!< 0x00000200 */ #define EXTI_EMR1_EM9 EXTI_EMR1_EM9_Msk /*!< Event Mask on line 9 */ #define EXTI_EMR1_EM10_Pos (10U) #define EXTI_EMR1_EM10_Msk (0x1UL << EXTI_EMR1_EM10_Pos) /*!< 0x00000400 */ #define EXTI_EMR1_EM10 EXTI_EMR1_EM10_Msk /*!< Event Mask on line 10 */ #define EXTI_EMR1_EM11_Pos (11U) #define EXTI_EMR1_EM11_Msk (0x1UL << EXTI_EMR1_EM11_Pos) /*!< 0x00000800 */ #define EXTI_EMR1_EM11 EXTI_EMR1_EM11_Msk /*!< Event Mask on line 11 */ #define EXTI_EMR1_EM12_Pos (12U) #define EXTI_EMR1_EM12_Msk (0x1UL << EXTI_EMR1_EM12_Pos) /*!< 0x00001000 */ #define EXTI_EMR1_EM12 EXTI_EMR1_EM12_Msk /*!< Event Mask on line 12 */ #define EXTI_EMR1_EM13_Pos (13U) #define EXTI_EMR1_EM13_Msk (0x1UL << EXTI_EMR1_EM13_Pos) /*!< 0x00002000 */ #define EXTI_EMR1_EM13 EXTI_EMR1_EM13_Msk /*!< Event Mask on line 13 */ #define EXTI_EMR1_EM14_Pos (14U) #define EXTI_EMR1_EM14_Msk (0x1UL << EXTI_EMR1_EM14_Pos) /*!< 0x00004000 */ #define EXTI_EMR1_EM14 EXTI_EMR1_EM14_Msk /*!< Event Mask on line 14 */ #define EXTI_EMR1_EM15_Pos (15U) #define EXTI_EMR1_EM15_Msk (0x1UL << EXTI_EMR1_EM15_Pos) /*!< 0x00008000 */ #define EXTI_EMR1_EM15 EXTI_EMR1_EM15_Msk /*!< Event Mask on line 15 */ #define EXTI_EMR1_EM16_Pos (16U) #define EXTI_EMR1_EM16_Msk (0x1UL << EXTI_EMR1_EM16_Pos) /*!< 0x00010000 */ #define EXTI_EMR1_EM16 EXTI_EMR1_EM16_Msk /*!< Event Mask on line 16 */ #define EXTI_EMR1_EM17_Pos (17U) #define EXTI_EMR1_EM17_Msk (0x1UL << EXTI_EMR1_EM17_Pos) /*!< 0x00020000 */ #define EXTI_EMR1_EM17 EXTI_EMR1_EM17_Msk /*!< Event Mask on line 17 */ #define EXTI_EMR1_EM18_Pos (18U) #define EXTI_EMR1_EM18_Msk (0x1UL << EXTI_EMR1_EM18_Pos) /*!< 0x00040000 */ #define EXTI_EMR1_EM18 EXTI_EMR1_EM18_Msk /*!< Event Mask on line 18 */ #define EXTI_EMR1_EM19_Pos (19U) #define EXTI_EMR1_EM19_Msk (0x1UL << EXTI_EMR1_EM19_Pos) /*!< 0x00080000 */ #define EXTI_EMR1_EM19 EXTI_EMR1_EM19_Msk /*!< Event Mask on line 19 */ #define EXTI_EMR1_EM21_Pos (21U) #define EXTI_EMR1_EM21_Msk (0x1UL << EXTI_EMR1_EM21_Pos) /*!< 0x00200000 */ #define EXTI_EMR1_EM21 EXTI_EMR1_EM21_Msk /*!< Event Mask on line 21 */ #define EXTI_EMR1_EM23_Pos (23U) #define EXTI_EMR1_EM23_Msk (0x1UL << EXTI_EMR1_EM23_Pos) /*!< 0x00800000 */ #define EXTI_EMR1_EM23 EXTI_EMR1_EM23_Msk /*!< Event Mask on line 23 */ #define EXTI_EMR1_EM25_Pos (25U) #define EXTI_EMR1_EM25_Msk (0x1UL << EXTI_EMR1_EM25_Pos) /*!< 0x02000000 */ #define EXTI_EMR1_EM25 EXTI_EMR1_EM25_Msk /*!< Event Mask on line 25 */ #define EXTI_EMR1_EM26_Pos (26U) #define EXTI_EMR1_EM26_Msk (0x1UL << EXTI_EMR1_EM26_Pos) /*!< 0x04000000 */ #define EXTI_EMR1_EM26 EXTI_EMR1_EM26_Msk /*!< Event Mask on line 26 */ #define EXTI_EMR1_EM27_Pos (27U) #define EXTI_EMR1_EM27_Msk (0x1UL << EXTI_EMR1_EM27_Pos) /*!< 0x08000000 */ #define EXTI_EMR1_EM27 EXTI_EMR1_EM27_Msk /*!< Event Mask on line 27 */ #define EXTI_EMR1_EM28_Pos (28U) #define EXTI_EMR1_EM28_Msk (0x1UL << EXTI_EMR1_EM28_Pos) /*!< 0x10000000 */ #define EXTI_EMR1_EM28 EXTI_EMR1_EM28_Msk /*!< Event Mask on line 28 */ #define EXTI_EMR1_EM29_Pos (29U) #define EXTI_EMR1_EM29_Msk (0x1UL << EXTI_EMR1_EM29_Pos) /*!< 0x20000000 */ #define EXTI_EMR1_EM29 EXTI_EMR1_EM29_Msk /*!< Event Mask on line 29 */ #define EXTI_EMR1_EM30_Pos (30U) #define EXTI_EMR1_EM30_Msk (0x1UL << EXTI_EMR1_EM30_Pos) /*!< 0x40000000 */ #define EXTI_EMR1_EM30 EXTI_EMR1_EM30_Msk /*!< Event Mask on line 30 */ #define EXTI_EMR1_EM31_Pos (31U) #define EXTI_EMR1_EM31_Msk (0x1UL << EXTI_EMR1_EM31_Pos) /*!< 0x80000000 */ #define EXTI_EMR1_EM31 EXTI_EMR1_EM31_Msk /*!< Event Mask on line 31 */ /******************************************************************************/ /* */ /* FLASH */ /* */ /******************************************************************************/ #define GPIO_NRST_CONFIG_SUPPORT /*!< GPIO feature available only on specific devices: Configure NRST pin */ #define FLASH_SECURABLE_MEMORY_SUPPORT /*!< Flash feature available only on specific devices: allow to secure memory */ #define FLASH_PCROP_SUPPORT /*!< Flash feature available only on specific devices: proprietary code read protection areas selected by option */ /******************* Bits definition for FLASH_ACR register *****************/ #define FLASH_ACR_LATENCY_Pos (0U) #define FLASH_ACR_LATENCY_Msk (0x7UL << FLASH_ACR_LATENCY_Pos) /*!< 0x00000007 */ #define FLASH_ACR_LATENCY FLASH_ACR_LATENCY_Msk #define FLASH_ACR_LATENCY_0 (0x1UL << FLASH_ACR_LATENCY_Pos) /*!< 0x00000001 */ #define FLASH_ACR_LATENCY_1 (0x2UL << FLASH_ACR_LATENCY_Pos) /*!< 0x00000002 */ #define FLASH_ACR_PRFTEN_Pos (8U) #define FLASH_ACR_PRFTEN_Msk (0x1UL << FLASH_ACR_PRFTEN_Pos) /*!< 0x00000100 */ #define FLASH_ACR_PRFTEN FLASH_ACR_PRFTEN_Msk #define FLASH_ACR_ICEN_Pos (9U) #define FLASH_ACR_ICEN_Msk (0x1UL << FLASH_ACR_ICEN_Pos) /*!< 0x00000200 */ #define FLASH_ACR_ICEN FLASH_ACR_ICEN_Msk #define FLASH_ACR_ICRST_Pos (11U) #define FLASH_ACR_ICRST_Msk (0x1UL << FLASH_ACR_ICRST_Pos) /*!< 0x00000800 */ #define FLASH_ACR_ICRST FLASH_ACR_ICRST_Msk #define FLASH_ACR_PROGEMPTY_Pos (16U) #define FLASH_ACR_PROGEMPTY_Msk (0x1UL << FLASH_ACR_PROGEMPTY_Pos) /*!< 0x00010000 */ #define FLASH_ACR_PROGEMPTY FLASH_ACR_PROGEMPTY_Msk #define FLASH_ACR_DBG_SWEN_Pos (18U) #define FLASH_ACR_DBG_SWEN_Msk (0x1UL << FLASH_ACR_DBG_SWEN_Pos) /*!< 0x00040000 */ #define FLASH_ACR_DBG_SWEN FLASH_ACR_DBG_SWEN_Msk /******************* Bits definition for FLASH_SR register ******************/ #define FLASH_SR_EOP_Pos (0U) #define FLASH_SR_EOP_Msk (0x1UL << FLASH_SR_EOP_Pos) /*!< 0x00000001 */ #define FLASH_SR_EOP FLASH_SR_EOP_Msk #define FLASH_SR_OPERR_Pos (1U) #define FLASH_SR_OPERR_Msk (0x1UL << FLASH_SR_OPERR_Pos) /*!< 0x00000002 */ #define FLASH_SR_OPERR FLASH_SR_OPERR_Msk #define FLASH_SR_PROGERR_Pos (3U) #define FLASH_SR_PROGERR_Msk (0x1UL << FLASH_SR_PROGERR_Pos) /*!< 0x00000008 */ #define FLASH_SR_PROGERR FLASH_SR_PROGERR_Msk #define FLASH_SR_WRPERR_Pos (4U) #define FLASH_SR_WRPERR_Msk (0x1UL << FLASH_SR_WRPERR_Pos) /*!< 0x00000010 */ #define FLASH_SR_WRPERR FLASH_SR_WRPERR_Msk #define FLASH_SR_PGAERR_Pos (5U) #define FLASH_SR_PGAERR_Msk (0x1UL << FLASH_SR_PGAERR_Pos) /*!< 0x00000020 */ #define FLASH_SR_PGAERR FLASH_SR_PGAERR_Msk #define FLASH_SR_SIZERR_Pos (6U) #define FLASH_SR_SIZERR_Msk (0x1UL << FLASH_SR_SIZERR_Pos) /*!< 0x00000040 */ #define FLASH_SR_SIZERR FLASH_SR_SIZERR_Msk #define FLASH_SR_PGSERR_Pos (7U) #define FLASH_SR_PGSERR_Msk (0x1UL << FLASH_SR_PGSERR_Pos) /*!< 0x00000080 */ #define FLASH_SR_PGSERR FLASH_SR_PGSERR_Msk #define FLASH_SR_MISERR_Pos (8U) #define FLASH_SR_MISERR_Msk (0x1UL << FLASH_SR_MISERR_Pos) /*!< 0x00000100 */ #define FLASH_SR_MISERR FLASH_SR_MISERR_Msk #define FLASH_SR_FASTERR_Pos (9U) #define FLASH_SR_FASTERR_Msk (0x1UL << FLASH_SR_FASTERR_Pos) /*!< 0x00000200 */ #define FLASH_SR_FASTERR FLASH_SR_FASTERR_Msk #define FLASH_SR_RDERR_Pos (14U) #define FLASH_SR_RDERR_Msk (0x1UL << FLASH_SR_RDERR_Pos) /*!< 0x00004000 */ #define FLASH_SR_RDERR FLASH_SR_RDERR_Msk #define FLASH_SR_OPTVERR_Pos (15U) #define FLASH_SR_OPTVERR_Msk (0x1UL << FLASH_SR_OPTVERR_Pos) /*!< 0x00008000 */ #define FLASH_SR_OPTVERR FLASH_SR_OPTVERR_Msk #define FLASH_SR_BSY1_Pos (16U) #define FLASH_SR_BSY1_Msk (0x1UL << FLASH_SR_BSY1_Pos) /*!< 0x00010000 */ #define FLASH_SR_BSY1 FLASH_SR_BSY1_Msk #define FLASH_SR_CFGBSY_Pos (18U) #define FLASH_SR_CFGBSY_Msk (0x1UL << FLASH_SR_CFGBSY_Pos) /*!< 0x00040000 */ #define FLASH_SR_CFGBSY FLASH_SR_CFGBSY_Msk /******************* Bits definition for FLASH_CR register ******************/ #define FLASH_CR_PG_Pos (0U) #define FLASH_CR_PG_Msk (0x1UL << FLASH_CR_PG_Pos) /*!< 0x00000001 */ #define FLASH_CR_PG FLASH_CR_PG_Msk #define FLASH_CR_PER_Pos (1U) #define FLASH_CR_PER_Msk (0x1UL << FLASH_CR_PER_Pos) /*!< 0x00000002 */ #define FLASH_CR_PER FLASH_CR_PER_Msk #define FLASH_CR_MER1_Pos (2U) #define FLASH_CR_MER1_Msk (0x1UL << FLASH_CR_MER1_Pos) /*!< 0x00000004 */ #define FLASH_CR_MER1 FLASH_CR_MER1_Msk #define FLASH_CR_PNB_Pos (3U) #define FLASH_CR_PNB_Msk (0xFUL << FLASH_CR_PNB_Pos) /*!< 0x000001F8 */ #define FLASH_CR_PNB FLASH_CR_PNB_Msk #define FLASH_CR_STRT_Pos (16U) #define FLASH_CR_STRT_Msk (0x1UL << FLASH_CR_STRT_Pos) /*!< 0x00010000 */ #define FLASH_CR_STRT FLASH_CR_STRT_Msk #define FLASH_CR_OPTSTRT_Pos (17U) #define FLASH_CR_OPTSTRT_Msk (0x1UL << FLASH_CR_OPTSTRT_Pos) /*!< 0x00020000 */ #define FLASH_CR_OPTSTRT FLASH_CR_OPTSTRT_Msk #define FLASH_CR_FSTPG_Pos (18U) #define FLASH_CR_FSTPG_Msk (0x1UL << FLASH_CR_FSTPG_Pos) /*!< 0x00040000 */ #define FLASH_CR_FSTPG FLASH_CR_FSTPG_Msk #define FLASH_CR_EOPIE_Pos (24U) #define FLASH_CR_EOPIE_Msk (0x1UL << FLASH_CR_EOPIE_Pos) /*!< 0x01000000 */ #define FLASH_CR_EOPIE FLASH_CR_EOPIE_Msk #define FLASH_CR_ERRIE_Pos (25U) #define FLASH_CR_ERRIE_Msk (0x1UL << FLASH_CR_ERRIE_Pos) /*!< 0x02000000 */ #define FLASH_CR_ERRIE FLASH_CR_ERRIE_Msk #define FLASH_CR_RDERRIE_Pos (26U) #define FLASH_CR_RDERRIE_Msk (0x1UL << FLASH_CR_RDERRIE_Pos) /*!< 0x04000000 */ #define FLASH_CR_RDERRIE FLASH_CR_RDERRIE_Msk #define FLASH_CR_OBL_LAUNCH_Pos (27U) #define FLASH_CR_OBL_LAUNCH_Msk (0x1UL << FLASH_CR_OBL_LAUNCH_Pos) /*!< 0x08000000 */ #define FLASH_CR_OBL_LAUNCH FLASH_CR_OBL_LAUNCH_Msk #define FLASH_CR_SEC_PROT_Pos (28U) #define FLASH_CR_SEC_PROT_Msk (0x1UL << FLASH_CR_SEC_PROT_Pos) /*!< 0x10000000 */ #define FLASH_CR_SEC_PROT FLASH_CR_SEC_PROT_Msk #define FLASH_CR_OPTLOCK_Pos (30U) #define FLASH_CR_OPTLOCK_Msk (0x1UL << FLASH_CR_OPTLOCK_Pos) /*!< 0x40000000 */ #define FLASH_CR_OPTLOCK FLASH_CR_OPTLOCK_Msk #define FLASH_CR_LOCK_Pos (31U) #define FLASH_CR_LOCK_Msk (0x1UL << FLASH_CR_LOCK_Pos) /*!< 0x80000000 */ #define FLASH_CR_LOCK FLASH_CR_LOCK_Msk /******************* Bits definition for FLASH_ECCR register ****************/ #define FLASH_ECCR_ADDR_ECC_Pos (0U) #define FLASH_ECCR_ADDR_ECC_Msk (0x3FFFUL << FLASH_ECCR_ADDR_ECC_Pos) /*!< 0x00003FFF */ #define FLASH_ECCR_ADDR_ECC FLASH_ECCR_ADDR_ECC_Msk #define FLASH_ECCR_SYSF_ECC_Pos (20U) #define FLASH_ECCR_SYSF_ECC_Msk (0x1UL << FLASH_ECCR_SYSF_ECC_Pos) /*!< 0x00100000 */ #define FLASH_ECCR_SYSF_ECC FLASH_ECCR_SYSF_ECC_Msk #define FLASH_ECCR_ECCCIE_Pos (24U) #define FLASH_ECCR_ECCCIE_Msk (0x1UL << FLASH_ECCR_ECCCIE_Pos) /*!< 0x01000000 */ #define FLASH_ECCR_ECCCIE FLASH_ECCR_ECCCIE_Msk #define FLASH_ECCR_ECCC_Pos (30U) #define FLASH_ECCR_ECCC_Msk (0x1UL << FLASH_ECCR_ECCC_Pos) /*!< 0x40000000 */ #define FLASH_ECCR_ECCC FLASH_ECCR_ECCC_Msk #define FLASH_ECCR_ECCD_Pos (31U) #define FLASH_ECCR_ECCD_Msk (0x1UL << FLASH_ECCR_ECCD_Pos) /*!< 0x80000000 */ #define FLASH_ECCR_ECCD FLASH_ECCR_ECCD_Msk /******************* Bits definition for FLASH_OPTR register ****************/ #define FLASH_OPTR_RDP_Pos (0U) #define FLASH_OPTR_RDP_Msk (0xFFUL << FLASH_OPTR_RDP_Pos) /*!< 0x000000FF */ #define FLASH_OPTR_RDP FLASH_OPTR_RDP_Msk #define FLASH_OPTR_BOR_EN_Pos (8U) #define FLASH_OPTR_BOR_EN_Msk (0x1UL << FLASH_OPTR_BOR_EN_Pos) /*!< 0x00000100 */ #define FLASH_OPTR_BOR_EN FLASH_OPTR_BOR_EN_Msk #define FLASH_OPTR_BORF_LEV_Pos (9U) #define FLASH_OPTR_BORF_LEV_Msk (0x3UL << FLASH_OPTR_BORF_LEV_Pos) /*!< 0x00000600 */ #define FLASH_OPTR_BORF_LEV FLASH_OPTR_BORF_LEV_Msk #define FLASH_OPTR_BORF_LEV_0 (0x1UL << FLASH_OPTR_BORF_LEV_Pos) /*!< 0x00000200 */ #define FLASH_OPTR_BORF_LEV_1 (0x2UL << FLASH_OPTR_BORF_LEV_Pos) /*!< 0x00000400 */ #define FLASH_OPTR_BORR_LEV_Pos (11U) #define FLASH_OPTR_BORR_LEV_Msk (0x3UL << FLASH_OPTR_BORR_LEV_Pos) /*!< 0x00001800 */ #define FLASH_OPTR_BORR_LEV FLASH_OPTR_BORR_LEV_Msk #define FLASH_OPTR_BORR_LEV_0 (0x1UL << FLASH_OPTR_BORR_LEV_Pos) /*!< 0x00000800 */ #define FLASH_OPTR_BORR_LEV_1 (0x2UL << FLASH_OPTR_BORR_LEV_Pos) /*!< 0x00001000 */ #define FLASH_OPTR_nRST_STOP_Pos (13U) #define FLASH_OPTR_nRST_STOP_Msk (0x1UL << FLASH_OPTR_nRST_STOP_Pos) /*!< 0x00002000 */ #define FLASH_OPTR_nRST_STOP FLASH_OPTR_nRST_STOP_Msk #define FLASH_OPTR_nRST_STDBY_Pos (14U) #define FLASH_OPTR_nRST_STDBY_Msk (0x1UL << FLASH_OPTR_nRST_STDBY_Pos) /*!< 0x00004000 */ #define FLASH_OPTR_nRST_STDBY FLASH_OPTR_nRST_STDBY_Msk #define FLASH_OPTR_nRST_SHDW_Pos (15U) #define FLASH_OPTR_nRST_SHDW_Msk (0x1UL << FLASH_OPTR_nRST_SHDW_Pos) /*!< 0x00008000 */ #define FLASH_OPTR_nRST_SHDW FLASH_OPTR_nRST_SHDW_Msk #define FLASH_OPTR_IWDG_SW_Pos (16U) #define FLASH_OPTR_IWDG_SW_Msk (0x1UL << FLASH_OPTR_IWDG_SW_Pos) /*!< 0x00010000 */ #define FLASH_OPTR_IWDG_SW FLASH_OPTR_IWDG_SW_Msk #define FLASH_OPTR_IWDG_STOP_Pos (17U) #define FLASH_OPTR_IWDG_STOP_Msk (0x1UL << FLASH_OPTR_IWDG_STOP_Pos) /*!< 0x00020000 */ #define FLASH_OPTR_IWDG_STOP FLASH_OPTR_IWDG_STOP_Msk #define FLASH_OPTR_IWDG_STDBY_Pos (18U) #define FLASH_OPTR_IWDG_STDBY_Msk (0x1UL << FLASH_OPTR_IWDG_STDBY_Pos) /*!< 0x00040000 */ #define FLASH_OPTR_IWDG_STDBY FLASH_OPTR_IWDG_STDBY_Msk #define FLASH_OPTR_WWDG_SW_Pos (19U) #define FLASH_OPTR_WWDG_SW_Msk (0x1UL << FLASH_OPTR_WWDG_SW_Pos) /*!< 0x00080000 */ #define FLASH_OPTR_WWDG_SW FLASH_OPTR_WWDG_SW_Msk #define FLASH_OPTR_RAM_PARITY_CHECK_Pos (22U) #define FLASH_OPTR_RAM_PARITY_CHECK_Msk (0x1UL << FLASH_OPTR_RAM_PARITY_CHECK_Pos) /*!< 0x00400000 */ #define FLASH_OPTR_RAM_PARITY_CHECK FLASH_OPTR_RAM_PARITY_CHECK_Msk #define FLASH_OPTR_nBOOT_SEL_Pos (24U) #define FLASH_OPTR_nBOOT_SEL_Msk (0x1UL << FLASH_OPTR_nBOOT_SEL_Pos) /*!< 0x01000000 */ #define FLASH_OPTR_nBOOT_SEL FLASH_OPTR_nBOOT_SEL_Msk #define FLASH_OPTR_nBOOT1_Pos (25U) #define FLASH_OPTR_nBOOT1_Msk (0x1UL << FLASH_OPTR_nBOOT1_Pos) /*!< 0x02000000 */ #define FLASH_OPTR_nBOOT1 FLASH_OPTR_nBOOT1_Msk #define FLASH_OPTR_nBOOT0_Pos (26U) #define FLASH_OPTR_nBOOT0_Msk (0x1UL << FLASH_OPTR_nBOOT0_Pos) /*!< 0x04000000 */ #define FLASH_OPTR_nBOOT0 FLASH_OPTR_nBOOT0_Msk #define FLASH_OPTR_NRST_MODE_Pos (27U) #define FLASH_OPTR_NRST_MODE_Msk (0x3UL << FLASH_OPTR_NRST_MODE_Pos) /*!< 0x18000000 */ #define FLASH_OPTR_NRST_MODE FLASH_OPTR_NRST_MODE_Msk #define FLASH_OPTR_NRST_MODE_0 (0x1UL << FLASH_OPTR_NRST_MODE_Pos) /*!< 0x08000000 */ #define FLASH_OPTR_NRST_MODE_1 (0x2UL << FLASH_OPTR_NRST_MODE_Pos) /*!< 0x10000000 */ #define FLASH_OPTR_IRHEN_Pos (29U) #define FLASH_OPTR_IRHEN_Msk (0x1UL << FLASH_OPTR_IRHEN_Pos) /*!< 0x20000000 */ #define FLASH_OPTR_IRHEN FLASH_OPTR_IRHEN_Msk /****************** Bits definition for FLASH_PCROP1ASR register ************/ #define FLASH_PCROP1ASR_PCROP1A_STRT_Pos (0U) #define FLASH_PCROP1ASR_PCROP1A_STRT_Msk (0x7FUL << FLASH_PCROP1ASR_PCROP1A_STRT_Pos) /*!< 0x0000007F */ #define FLASH_PCROP1ASR_PCROP1A_STRT FLASH_PCROP1ASR_PCROP1A_STRT_Msk /****************** Bits definition for FLASH_PCROP1AER register ************/ #define FLASH_PCROP1AER_PCROP1A_END_Pos (0U) #define FLASH_PCROP1AER_PCROP1A_END_Msk (0x7FUL << FLASH_PCROP1AER_PCROP1A_END_Pos) /*!< 0x0000007F */ #define FLASH_PCROP1AER_PCROP1A_END FLASH_PCROP1AER_PCROP1A_END_Msk #define FLASH_PCROP1AER_PCROP_RDP_Pos (31U) #define FLASH_PCROP1AER_PCROP_RDP_Msk (0x1UL << FLASH_PCROP1AER_PCROP_RDP_Pos) /*!< 0x80000000 */ #define FLASH_PCROP1AER_PCROP_RDP FLASH_PCROP1AER_PCROP_RDP_Msk /****************** Bits definition for FLASH_WRP1AR register ***************/ #define FLASH_WRP1AR_WRP1A_STRT_Pos (0U) #define FLASH_WRP1AR_WRP1A_STRT_Msk (0x1FUL << FLASH_WRP1AR_WRP1A_STRT_Pos) /*!< 0x0000001F */ #define FLASH_WRP1AR_WRP1A_STRT FLASH_WRP1AR_WRP1A_STRT_Msk #define FLASH_WRP1AR_WRP1A_END_Pos (16U) #define FLASH_WRP1AR_WRP1A_END_Msk (0x1FUL << FLASH_WRP1AR_WRP1A_END_Pos) /*!< 0x001F0000 */ #define FLASH_WRP1AR_WRP1A_END FLASH_WRP1AR_WRP1A_END_Msk /****************** Bits definition for FLASH_WRP1BR register ***************/ #define FLASH_WRP1BR_WRP1B_STRT_Pos (0U) #define FLASH_WRP1BR_WRP1B_STRT_Msk (0x1FUL << FLASH_WRP1BR_WRP1B_STRT_Pos) /*!< 0x0000001F */ #define FLASH_WRP1BR_WRP1B_STRT FLASH_WRP1BR_WRP1B_STRT_Msk #define FLASH_WRP1BR_WRP1B_END_Pos (16U) #define FLASH_WRP1BR_WRP1B_END_Msk (0x1FUL << FLASH_WRP1BR_WRP1B_END_Pos) /*!< 0x001F0000 */ #define FLASH_WRP1BR_WRP1B_END FLASH_WRP1BR_WRP1B_END_Msk /****************** Bits definition for FLASH_PCROP1BSR register ************/ #define FLASH_PCROP1BSR_PCROP1B_STRT_Pos (0U) #define FLASH_PCROP1BSR_PCROP1B_STRT_Msk (0x7FUL << FLASH_PCROP1BSR_PCROP1B_STRT_Pos) /*!< 0x0000007F */ #define FLASH_PCROP1BSR_PCROP1B_STRT FLASH_PCROP1BSR_PCROP1B_STRT_Msk /****************** Bits definition for FLASH_PCROP1BER register ************/ #define FLASH_PCROP1BER_PCROP1B_END_Pos (0U) #define FLASH_PCROP1BER_PCROP1B_END_Msk (0x7FUL << FLASH_PCROP1BER_PCROP1B_END_Pos) /*!< 0x0000007F */ #define FLASH_PCROP1BER_PCROP1B_END FLASH_PCROP1BER_PCROP1B_END_Msk /****************** Bits definition for FLASH_SECR register *****************/ #define FLASH_SECR_SEC_SIZE_Pos (0U) #define FLASH_SECR_SEC_SIZE_Msk (0x3FUL << FLASH_SECR_SEC_SIZE_Pos) /*!< 0x0000003F */ #define FLASH_SECR_SEC_SIZE FLASH_SECR_SEC_SIZE_Msk #define FLASH_SECR_BOOT_LOCK_Pos (16U) #define FLASH_SECR_BOOT_LOCK_Msk (0x1UL << FLASH_SECR_BOOT_LOCK_Pos) /*!< 0x00010000 */ #define FLASH_SECR_BOOT_LOCK FLASH_SECR_BOOT_LOCK_Msk /******************************************************************************/ /* */ /* General Purpose I/O */ /* */ /******************************************************************************/ /****************** Bits definition for GPIO_MODER register *****************/ #define GPIO_MODER_MODE0_Pos (0U) #define GPIO_MODER_MODE0_Msk (0x3UL << GPIO_MODER_MODE0_Pos) /*!< 0x00000003 */ #define GPIO_MODER_MODE0 GPIO_MODER_MODE0_Msk #define GPIO_MODER_MODE0_0 (0x1UL << GPIO_MODER_MODE0_Pos) /*!< 0x00000001 */ #define GPIO_MODER_MODE0_1 (0x2UL << GPIO_MODER_MODE0_Pos) /*!< 0x00000002 */ #define GPIO_MODER_MODE1_Pos (2U) #define GPIO_MODER_MODE1_Msk (0x3UL << GPIO_MODER_MODE1_Pos) /*!< 0x0000000C */ #define GPIO_MODER_MODE1 GPIO_MODER_MODE1_Msk #define GPIO_MODER_MODE1_0 (0x1UL << GPIO_MODER_MODE1_Pos) /*!< 0x00000004 */ #define GPIO_MODER_MODE1_1 (0x2UL << GPIO_MODER_MODE1_Pos) /*!< 0x00000008 */ #define GPIO_MODER_MODE2_Pos (4U) #define GPIO_MODER_MODE2_Msk (0x3UL << GPIO_MODER_MODE2_Pos) /*!< 0x00000030 */ #define GPIO_MODER_MODE2 GPIO_MODER_MODE2_Msk #define GPIO_MODER_MODE2_0 (0x1UL << GPIO_MODER_MODE2_Pos) /*!< 0x00000010 */ #define GPIO_MODER_MODE2_1 (0x2UL << GPIO_MODER_MODE2_Pos) /*!< 0x00000020 */ #define GPIO_MODER_MODE3_Pos (6U) #define GPIO_MODER_MODE3_Msk (0x3UL << GPIO_MODER_MODE3_Pos) /*!< 0x000000C0 */ #define GPIO_MODER_MODE3 GPIO_MODER_MODE3_Msk #define GPIO_MODER_MODE3_0 (0x1UL << GPIO_MODER_MODE3_Pos) /*!< 0x00000040 */ #define GPIO_MODER_MODE3_1 (0x2UL << GPIO_MODER_MODE3_Pos) /*!< 0x00000080 */ #define GPIO_MODER_MODE4_Pos (8U) #define GPIO_MODER_MODE4_Msk (0x3UL << GPIO_MODER_MODE4_Pos) /*!< 0x00000300 */ #define GPIO_MODER_MODE4 GPIO_MODER_MODE4_Msk #define GPIO_MODER_MODE4_0 (0x1UL << GPIO_MODER_MODE4_Pos) /*!< 0x00000100 */ #define GPIO_MODER_MODE4_1 (0x2UL << GPIO_MODER_MODE4_Pos) /*!< 0x00000200 */ #define GPIO_MODER_MODE5_Pos (10U) #define GPIO_MODER_MODE5_Msk (0x3UL << GPIO_MODER_MODE5_Pos) /*!< 0x00000C00 */ #define GPIO_MODER_MODE5 GPIO_MODER_MODE5_Msk #define GPIO_MODER_MODE5_0 (0x1UL << GPIO_MODER_MODE5_Pos) /*!< 0x00000400 */ #define GPIO_MODER_MODE5_1 (0x2UL << GPIO_MODER_MODE5_Pos) /*!< 0x00000800 */ #define GPIO_MODER_MODE6_Pos (12U) #define GPIO_MODER_MODE6_Msk (0x3UL << GPIO_MODER_MODE6_Pos) /*!< 0x00003000 */ #define GPIO_MODER_MODE6 GPIO_MODER_MODE6_Msk #define GPIO_MODER_MODE6_0 (0x1UL << GPIO_MODER_MODE6_Pos) /*!< 0x00001000 */ #define GPIO_MODER_MODE6_1 (0x2UL << GPIO_MODER_MODE6_Pos) /*!< 0x00002000 */ #define GPIO_MODER_MODE7_Pos (14U) #define GPIO_MODER_MODE7_Msk (0x3UL << GPIO_MODER_MODE7_Pos) /*!< 0x0000C000 */ #define GPIO_MODER_MODE7 GPIO_MODER_MODE7_Msk #define GPIO_MODER_MODE7_0 (0x1UL << GPIO_MODER_MODE7_Pos) /*!< 0x00004000 */ #define GPIO_MODER_MODE7_1 (0x2UL << GPIO_MODER_MODE7_Pos) /*!< 0x00008000 */ #define GPIO_MODER_MODE8_Pos (16U) #define GPIO_MODER_MODE8_Msk (0x3UL << GPIO_MODER_MODE8_Pos) /*!< 0x00030000 */ #define GPIO_MODER_MODE8 GPIO_MODER_MODE8_Msk #define GPIO_MODER_MODE8_0 (0x1UL << GPIO_MODER_MODE8_Pos) /*!< 0x00010000 */ #define GPIO_MODER_MODE8_1 (0x2UL << GPIO_MODER_MODE8_Pos) /*!< 0x00020000 */ #define GPIO_MODER_MODE9_Pos (18U) #define GPIO_MODER_MODE9_Msk (0x3UL << GPIO_MODER_MODE9_Pos) /*!< 0x000C0000 */ #define GPIO_MODER_MODE9 GPIO_MODER_MODE9_Msk #define GPIO_MODER_MODE9_0 (0x1UL << GPIO_MODER_MODE9_Pos) /*!< 0x00040000 */ #define GPIO_MODER_MODE9_1 (0x2UL << GPIO_MODER_MODE9_Pos) /*!< 0x00080000 */ #define GPIO_MODER_MODE10_Pos (20U) #define GPIO_MODER_MODE10_Msk (0x3UL << GPIO_MODER_MODE10_Pos) /*!< 0x00300000 */ #define GPIO_MODER_MODE10 GPIO_MODER_MODE10_Msk #define GPIO_MODER_MODE10_0 (0x1UL << GPIO_MODER_MODE10_Pos) /*!< 0x00100000 */ #define GPIO_MODER_MODE10_1 (0x2UL << GPIO_MODER_MODE10_Pos) /*!< 0x00200000 */ #define GPIO_MODER_MODE11_Pos (22U) #define GPIO_MODER_MODE11_Msk (0x3UL << GPIO_MODER_MODE11_Pos) /*!< 0x00C00000 */ #define GPIO_MODER_MODE11 GPIO_MODER_MODE11_Msk #define GPIO_MODER_MODE11_0 (0x1UL << GPIO_MODER_MODE11_Pos) /*!< 0x00400000 */ #define GPIO_MODER_MODE11_1 (0x2UL << GPIO_MODER_MODE11_Pos) /*!< 0x00800000 */ #define GPIO_MODER_MODE12_Pos (24U) #define GPIO_MODER_MODE12_Msk (0x3UL << GPIO_MODER_MODE12_Pos) /*!< 0x03000000 */ #define GPIO_MODER_MODE12 GPIO_MODER_MODE12_Msk #define GPIO_MODER_MODE12_0 (0x1UL << GPIO_MODER_MODE12_Pos) /*!< 0x01000000 */ #define GPIO_MODER_MODE12_1 (0x2UL << GPIO_MODER_MODE12_Pos) /*!< 0x02000000 */ #define GPIO_MODER_MODE13_Pos (26U) #define GPIO_MODER_MODE13_Msk (0x3UL << GPIO_MODER_MODE13_Pos) /*!< 0x0C000000 */ #define GPIO_MODER_MODE13 GPIO_MODER_MODE13_Msk #define GPIO_MODER_MODE13_0 (0x1UL << GPIO_MODER_MODE13_Pos) /*!< 0x04000000 */ #define GPIO_MODER_MODE13_1 (0x2UL << GPIO_MODER_MODE13_Pos) /*!< 0x08000000 */ #define GPIO_MODER_MODE14_Pos (28U) #define GPIO_MODER_MODE14_Msk (0x3UL << GPIO_MODER_MODE14_Pos) /*!< 0x30000000 */ #define GPIO_MODER_MODE14 GPIO_MODER_MODE14_Msk #define GPIO_MODER_MODE14_0 (0x1UL << GPIO_MODER_MODE14_Pos) /*!< 0x10000000 */ #define GPIO_MODER_MODE14_1 (0x2UL << GPIO_MODER_MODE14_Pos) /*!< 0x20000000 */ #define GPIO_MODER_MODE15_Pos (30U) #define GPIO_MODER_MODE15_Msk (0x3UL << GPIO_MODER_MODE15_Pos) /*!< 0xC0000000 */ #define GPIO_MODER_MODE15 GPIO_MODER_MODE15_Msk #define GPIO_MODER_MODE15_0 (0x1UL << GPIO_MODER_MODE15_Pos) /*!< 0x40000000 */ #define GPIO_MODER_MODE15_1 (0x2UL << GPIO_MODER_MODE15_Pos) /*!< 0x80000000 */ /****************** Bits definition for GPIO_OTYPER register ****************/ #define GPIO_OTYPER_OT0_Pos (0U) #define GPIO_OTYPER_OT0_Msk (0x1UL << GPIO_OTYPER_OT0_Pos) /*!< 0x00000001 */ #define GPIO_OTYPER_OT0 GPIO_OTYPER_OT0_Msk #define GPIO_OTYPER_OT1_Pos (1U) #define GPIO_OTYPER_OT1_Msk (0x1UL << GPIO_OTYPER_OT1_Pos) /*!< 0x00000002 */ #define GPIO_OTYPER_OT1 GPIO_OTYPER_OT1_Msk #define GPIO_OTYPER_OT2_Pos (2U) #define GPIO_OTYPER_OT2_Msk (0x1UL << GPIO_OTYPER_OT2_Pos) /*!< 0x00000004 */ #define GPIO_OTYPER_OT2 GPIO_OTYPER_OT2_Msk #define GPIO_OTYPER_OT3_Pos (3U) #define GPIO_OTYPER_OT3_Msk (0x1UL << GPIO_OTYPER_OT3_Pos) /*!< 0x00000008 */ #define GPIO_OTYPER_OT3 GPIO_OTYPER_OT3_Msk #define GPIO_OTYPER_OT4_Pos (4U) #define GPIO_OTYPER_OT4_Msk (0x1UL << GPIO_OTYPER_OT4_Pos) /*!< 0x00000010 */ #define GPIO_OTYPER_OT4 GPIO_OTYPER_OT4_Msk #define GPIO_OTYPER_OT5_Pos (5U) #define GPIO_OTYPER_OT5_Msk (0x1UL << GPIO_OTYPER_OT5_Pos) /*!< 0x00000020 */ #define GPIO_OTYPER_OT5 GPIO_OTYPER_OT5_Msk #define GPIO_OTYPER_OT6_Pos (6U) #define GPIO_OTYPER_OT6_Msk (0x1UL << GPIO_OTYPER_OT6_Pos) /*!< 0x00000040 */ #define GPIO_OTYPER_OT6 GPIO_OTYPER_OT6_Msk #define GPIO_OTYPER_OT7_Pos (7U) #define GPIO_OTYPER_OT7_Msk (0x1UL << GPIO_OTYPER_OT7_Pos) /*!< 0x00000080 */ #define GPIO_OTYPER_OT7 GPIO_OTYPER_OT7_Msk #define GPIO_OTYPER_OT8_Pos (8U) #define GPIO_OTYPER_OT8_Msk (0x1UL << GPIO_OTYPER_OT8_Pos) /*!< 0x00000100 */ #define GPIO_OTYPER_OT8 GPIO_OTYPER_OT8_Msk #define GPIO_OTYPER_OT9_Pos (9U) #define GPIO_OTYPER_OT9_Msk (0x1UL << GPIO_OTYPER_OT9_Pos) /*!< 0x00000200 */ #define GPIO_OTYPER_OT9 GPIO_OTYPER_OT9_Msk #define GPIO_OTYPER_OT10_Pos (10U) #define GPIO_OTYPER_OT10_Msk (0x1UL << GPIO_OTYPER_OT10_Pos) /*!< 0x00000400 */ #define GPIO_OTYPER_OT10 GPIO_OTYPER_OT10_Msk #define GPIO_OTYPER_OT11_Pos (11U) #define GPIO_OTYPER_OT11_Msk (0x1UL << GPIO_OTYPER_OT11_Pos) /*!< 0x00000800 */ #define GPIO_OTYPER_OT11 GPIO_OTYPER_OT11_Msk #define GPIO_OTYPER_OT12_Pos (12U) #define GPIO_OTYPER_OT12_Msk (0x1UL << GPIO_OTYPER_OT12_Pos) /*!< 0x00001000 */ #define GPIO_OTYPER_OT12 GPIO_OTYPER_OT12_Msk #define GPIO_OTYPER_OT13_Pos (13U) #define GPIO_OTYPER_OT13_Msk (0x1UL << GPIO_OTYPER_OT13_Pos) /*!< 0x00002000 */ #define GPIO_OTYPER_OT13 GPIO_OTYPER_OT13_Msk #define GPIO_OTYPER_OT14_Pos (14U) #define GPIO_OTYPER_OT14_Msk (0x1UL << GPIO_OTYPER_OT14_Pos) /*!< 0x00004000 */ #define GPIO_OTYPER_OT14 GPIO_OTYPER_OT14_Msk #define GPIO_OTYPER_OT15_Pos (15U) #define GPIO_OTYPER_OT15_Msk (0x1UL << GPIO_OTYPER_OT15_Pos) /*!< 0x00008000 */ #define GPIO_OTYPER_OT15 GPIO_OTYPER_OT15_Msk /****************** Bits definition for GPIO_OSPEEDR register ***************/ #define GPIO_OSPEEDR_OSPEED0_Pos (0U) #define GPIO_OSPEEDR_OSPEED0_Msk (0x3UL << GPIO_OSPEEDR_OSPEED0_Pos) /*!< 0x00000003 */ #define GPIO_OSPEEDR_OSPEED0 GPIO_OSPEEDR_OSPEED0_Msk #define GPIO_OSPEEDR_OSPEED0_0 (0x1UL << GPIO_OSPEEDR_OSPEED0_Pos) /*!< 0x00000001 */ #define GPIO_OSPEEDR_OSPEED0_1 (0x2UL << GPIO_OSPEEDR_OSPEED0_Pos) /*!< 0x00000002 */ #define GPIO_OSPEEDR_OSPEED1_Pos (2U) #define GPIO_OSPEEDR_OSPEED1_Msk (0x3UL << GPIO_OSPEEDR_OSPEED1_Pos) /*!< 0x0000000C */ #define GPIO_OSPEEDR_OSPEED1 GPIO_OSPEEDR_OSPEED1_Msk #define GPIO_OSPEEDR_OSPEED1_0 (0x1UL << GPIO_OSPEEDR_OSPEED1_Pos) /*!< 0x00000004 */ #define GPIO_OSPEEDR_OSPEED1_1 (0x2UL << GPIO_OSPEEDR_OSPEED1_Pos) /*!< 0x00000008 */ #define GPIO_OSPEEDR_OSPEED2_Pos (4U) #define GPIO_OSPEEDR_OSPEED2_Msk (0x3UL << GPIO_OSPEEDR_OSPEED2_Pos) /*!< 0x00000030 */ #define GPIO_OSPEEDR_OSPEED2 GPIO_OSPEEDR_OSPEED2_Msk #define GPIO_OSPEEDR_OSPEED2_0 (0x1UL << GPIO_OSPEEDR_OSPEED2_Pos) /*!< 0x00000010 */ #define GPIO_OSPEEDR_OSPEED2_1 (0x2UL << GPIO_OSPEEDR_OSPEED2_Pos) /*!< 0x00000020 */ #define GPIO_OSPEEDR_OSPEED3_Pos (6U) #define GPIO_OSPEEDR_OSPEED3_Msk (0x3UL << GPIO_OSPEEDR_OSPEED3_Pos) /*!< 0x000000C0 */ #define GPIO_OSPEEDR_OSPEED3 GPIO_OSPEEDR_OSPEED3_Msk #define GPIO_OSPEEDR_OSPEED3_0 (0x1UL << GPIO_OSPEEDR_OSPEED3_Pos) /*!< 0x00000040 */ #define GPIO_OSPEEDR_OSPEED3_1 (0x2UL << GPIO_OSPEEDR_OSPEED3_Pos) /*!< 0x00000080 */ #define GPIO_OSPEEDR_OSPEED4_Pos (8U) #define GPIO_OSPEEDR_OSPEED4_Msk (0x3UL << GPIO_OSPEEDR_OSPEED4_Pos) /*!< 0x00000300 */ #define GPIO_OSPEEDR_OSPEED4 GPIO_OSPEEDR_OSPEED4_Msk #define GPIO_OSPEEDR_OSPEED4_0 (0x1UL << GPIO_OSPEEDR_OSPEED4_Pos) /*!< 0x00000100 */ #define GPIO_OSPEEDR_OSPEED4_1 (0x2UL << GPIO_OSPEEDR_OSPEED4_Pos) /*!< 0x00000200 */ #define GPIO_OSPEEDR_OSPEED5_Pos (10U) #define GPIO_OSPEEDR_OSPEED5_Msk (0x3UL << GPIO_OSPEEDR_OSPEED5_Pos) /*!< 0x00000C00 */ #define GPIO_OSPEEDR_OSPEED5 GPIO_OSPEEDR_OSPEED5_Msk #define GPIO_OSPEEDR_OSPEED5_0 (0x1UL << GPIO_OSPEEDR_OSPEED5_Pos) /*!< 0x00000400 */ #define GPIO_OSPEEDR_OSPEED5_1 (0x2UL << GPIO_OSPEEDR_OSPEED5_Pos) /*!< 0x00000800 */ #define GPIO_OSPEEDR_OSPEED6_Pos (12U) #define GPIO_OSPEEDR_OSPEED6_Msk (0x3UL << GPIO_OSPEEDR_OSPEED6_Pos) /*!< 0x00003000 */ #define GPIO_OSPEEDR_OSPEED6 GPIO_OSPEEDR_OSPEED6_Msk #define GPIO_OSPEEDR_OSPEED6_0 (0x1UL << GPIO_OSPEEDR_OSPEED6_Pos) /*!< 0x00001000 */ #define GPIO_OSPEEDR_OSPEED6_1 (0x2UL << GPIO_OSPEEDR_OSPEED6_Pos) /*!< 0x00002000 */ #define GPIO_OSPEEDR_OSPEED7_Pos (14U) #define GPIO_OSPEEDR_OSPEED7_Msk (0x3UL << GPIO_OSPEEDR_OSPEED7_Pos) /*!< 0x0000C000 */ #define GPIO_OSPEEDR_OSPEED7 GPIO_OSPEEDR_OSPEED7_Msk #define GPIO_OSPEEDR_OSPEED7_0 (0x1UL << GPIO_OSPEEDR_OSPEED7_Pos) /*!< 0x00004000 */ #define GPIO_OSPEEDR_OSPEED7_1 (0x2UL << GPIO_OSPEEDR_OSPEED7_Pos) /*!< 0x00008000 */ #define GPIO_OSPEEDR_OSPEED8_Pos (16U) #define GPIO_OSPEEDR_OSPEED8_Msk (0x3UL << GPIO_OSPEEDR_OSPEED8_Pos) /*!< 0x00030000 */ #define GPIO_OSPEEDR_OSPEED8 GPIO_OSPEEDR_OSPEED8_Msk #define GPIO_OSPEEDR_OSPEED8_0 (0x1UL << GPIO_OSPEEDR_OSPEED8_Pos) /*!< 0x00010000 */ #define GPIO_OSPEEDR_OSPEED8_1 (0x2UL << GPIO_OSPEEDR_OSPEED8_Pos) /*!< 0x00020000 */ #define GPIO_OSPEEDR_OSPEED9_Pos (18U) #define GPIO_OSPEEDR_OSPEED9_Msk (0x3UL << GPIO_OSPEEDR_OSPEED9_Pos) /*!< 0x000C0000 */ #define GPIO_OSPEEDR_OSPEED9 GPIO_OSPEEDR_OSPEED9_Msk #define GPIO_OSPEEDR_OSPEED9_0 (0x1UL << GPIO_OSPEEDR_OSPEED9_Pos) /*!< 0x00040000 */ #define GPIO_OSPEEDR_OSPEED9_1 (0x2UL << GPIO_OSPEEDR_OSPEED9_Pos) /*!< 0x00080000 */ #define GPIO_OSPEEDR_OSPEED10_Pos (20U) #define GPIO_OSPEEDR_OSPEED10_Msk (0x3UL << GPIO_OSPEEDR_OSPEED10_Pos) /*!< 0x00300000 */ #define GPIO_OSPEEDR_OSPEED10 GPIO_OSPEEDR_OSPEED10_Msk #define GPIO_OSPEEDR_OSPEED10_0 (0x1UL << GPIO_OSPEEDR_OSPEED10_Pos) /*!< 0x00100000 */ #define GPIO_OSPEEDR_OSPEED10_1 (0x2UL << GPIO_OSPEEDR_OSPEED10_Pos) /*!< 0x00200000 */ #define GPIO_OSPEEDR_OSPEED11_Pos (22U) #define GPIO_OSPEEDR_OSPEED11_Msk (0x3UL << GPIO_OSPEEDR_OSPEED11_Pos) /*!< 0x00C00000 */ #define GPIO_OSPEEDR_OSPEED11 GPIO_OSPEEDR_OSPEED11_Msk #define GPIO_OSPEEDR_OSPEED11_0 (0x1UL << GPIO_OSPEEDR_OSPEED11_Pos) /*!< 0x00400000 */ #define GPIO_OSPEEDR_OSPEED11_1 (0x2UL << GPIO_OSPEEDR_OSPEED11_Pos) /*!< 0x00800000 */ #define GPIO_OSPEEDR_OSPEED12_Pos (24U) #define GPIO_OSPEEDR_OSPEED12_Msk (0x3UL << GPIO_OSPEEDR_OSPEED12_Pos) /*!< 0x03000000 */ #define GPIO_OSPEEDR_OSPEED12 GPIO_OSPEEDR_OSPEED12_Msk #define GPIO_OSPEEDR_OSPEED12_0 (0x1UL << GPIO_OSPEEDR_OSPEED12_Pos) /*!< 0x01000000 */ #define GPIO_OSPEEDR_OSPEED12_1 (0x2UL << GPIO_OSPEEDR_OSPEED12_Pos) /*!< 0x02000000 */ #define GPIO_OSPEEDR_OSPEED13_Pos (26U) #define GPIO_OSPEEDR_OSPEED13_Msk (0x3UL << GPIO_OSPEEDR_OSPEED13_Pos) /*!< 0x0C000000 */ #define GPIO_OSPEEDR_OSPEED13 GPIO_OSPEEDR_OSPEED13_Msk #define GPIO_OSPEEDR_OSPEED13_0 (0x1UL << GPIO_OSPEEDR_OSPEED13_Pos) /*!< 0x04000000 */ #define GPIO_OSPEEDR_OSPEED13_1 (0x2UL << GPIO_OSPEEDR_OSPEED13_Pos) /*!< 0x08000000 */ #define GPIO_OSPEEDR_OSPEED14_Pos (28U) #define GPIO_OSPEEDR_OSPEED14_Msk (0x3UL << GPIO_OSPEEDR_OSPEED14_Pos) /*!< 0x30000000 */ #define GPIO_OSPEEDR_OSPEED14 GPIO_OSPEEDR_OSPEED14_Msk #define GPIO_OSPEEDR_OSPEED14_0 (0x1UL << GPIO_OSPEEDR_OSPEED14_Pos) /*!< 0x10000000 */ #define GPIO_OSPEEDR_OSPEED14_1 (0x2UL << GPIO_OSPEEDR_OSPEED14_Pos) /*!< 0x20000000 */ #define GPIO_OSPEEDR_OSPEED15_Pos (30U) #define GPIO_OSPEEDR_OSPEED15_Msk (0x3UL << GPIO_OSPEEDR_OSPEED15_Pos) /*!< 0xC0000000 */ #define GPIO_OSPEEDR_OSPEED15 GPIO_OSPEEDR_OSPEED15_Msk #define GPIO_OSPEEDR_OSPEED15_0 (0x1UL << GPIO_OSPEEDR_OSPEED15_Pos) /*!< 0x40000000 */ #define GPIO_OSPEEDR_OSPEED15_1 (0x2UL << GPIO_OSPEEDR_OSPEED15_Pos) /*!< 0x80000000 */ /****************** Bits definition for GPIO_PUPDR register *****************/ #define GPIO_PUPDR_PUPD0_Pos (0U) #define GPIO_PUPDR_PUPD0_Msk (0x3UL << GPIO_PUPDR_PUPD0_Pos) /*!< 0x00000003 */ #define GPIO_PUPDR_PUPD0 GPIO_PUPDR_PUPD0_Msk #define GPIO_PUPDR_PUPD0_0 (0x1UL << GPIO_PUPDR_PUPD0_Pos) /*!< 0x00000001 */ #define GPIO_PUPDR_PUPD0_1 (0x2UL << GPIO_PUPDR_PUPD0_Pos) /*!< 0x00000002 */ #define GPIO_PUPDR_PUPD1_Pos (2U) #define GPIO_PUPDR_PUPD1_Msk (0x3UL << GPIO_PUPDR_PUPD1_Pos) /*!< 0x0000000C */ #define GPIO_PUPDR_PUPD1 GPIO_PUPDR_PUPD1_Msk #define GPIO_PUPDR_PUPD1_0 (0x1UL << GPIO_PUPDR_PUPD1_Pos) /*!< 0x00000004 */ #define GPIO_PUPDR_PUPD1_1 (0x2UL << GPIO_PUPDR_PUPD1_Pos) /*!< 0x00000008 */ #define GPIO_PUPDR_PUPD2_Pos (4U) #define GPIO_PUPDR_PUPD2_Msk (0x3UL << GPIO_PUPDR_PUPD2_Pos) /*!< 0x00000030 */ #define GPIO_PUPDR_PUPD2 GPIO_PUPDR_PUPD2_Msk #define GPIO_PUPDR_PUPD2_0 (0x1UL << GPIO_PUPDR_PUPD2_Pos) /*!< 0x00000010 */ #define GPIO_PUPDR_PUPD2_1 (0x2UL << GPIO_PUPDR_PUPD2_Pos) /*!< 0x00000020 */ #define GPIO_PUPDR_PUPD3_Pos (6U) #define GPIO_PUPDR_PUPD3_Msk (0x3UL << GPIO_PUPDR_PUPD3_Pos) /*!< 0x000000C0 */ #define GPIO_PUPDR_PUPD3 GPIO_PUPDR_PUPD3_Msk #define GPIO_PUPDR_PUPD3_0 (0x1UL << GPIO_PUPDR_PUPD3_Pos) /*!< 0x00000040 */ #define GPIO_PUPDR_PUPD3_1 (0x2UL << GPIO_PUPDR_PUPD3_Pos) /*!< 0x00000080 */ #define GPIO_PUPDR_PUPD4_Pos (8U) #define GPIO_PUPDR_PUPD4_Msk (0x3UL << GPIO_PUPDR_PUPD4_Pos) /*!< 0x00000300 */ #define GPIO_PUPDR_PUPD4 GPIO_PUPDR_PUPD4_Msk #define GPIO_PUPDR_PUPD4_0 (0x1UL << GPIO_PUPDR_PUPD4_Pos) /*!< 0x00000100 */ #define GPIO_PUPDR_PUPD4_1 (0x2UL << GPIO_PUPDR_PUPD4_Pos) /*!< 0x00000200 */ #define GPIO_PUPDR_PUPD5_Pos (10U) #define GPIO_PUPDR_PUPD5_Msk (0x3UL << GPIO_PUPDR_PUPD5_Pos) /*!< 0x00000C00 */ #define GPIO_PUPDR_PUPD5 GPIO_PUPDR_PUPD5_Msk #define GPIO_PUPDR_PUPD5_0 (0x1UL << GPIO_PUPDR_PUPD5_Pos) /*!< 0x00000400 */ #define GPIO_PUPDR_PUPD5_1 (0x2UL << GPIO_PUPDR_PUPD5_Pos) /*!< 0x00000800 */ #define GPIO_PUPDR_PUPD6_Pos (12U) #define GPIO_PUPDR_PUPD6_Msk (0x3UL << GPIO_PUPDR_PUPD6_Pos) /*!< 0x00003000 */ #define GPIO_PUPDR_PUPD6 GPIO_PUPDR_PUPD6_Msk #define GPIO_PUPDR_PUPD6_0 (0x1UL << GPIO_PUPDR_PUPD6_Pos) /*!< 0x00001000 */ #define GPIO_PUPDR_PUPD6_1 (0x2UL << GPIO_PUPDR_PUPD6_Pos) /*!< 0x00002000 */ #define GPIO_PUPDR_PUPD7_Pos (14U) #define GPIO_PUPDR_PUPD7_Msk (0x3UL << GPIO_PUPDR_PUPD7_Pos) /*!< 0x0000C000 */ #define GPIO_PUPDR_PUPD7 GPIO_PUPDR_PUPD7_Msk #define GPIO_PUPDR_PUPD7_0 (0x1UL << GPIO_PUPDR_PUPD7_Pos) /*!< 0x00004000 */ #define GPIO_PUPDR_PUPD7_1 (0x2UL << GPIO_PUPDR_PUPD7_Pos) /*!< 0x00008000 */ #define GPIO_PUPDR_PUPD8_Pos (16U) #define GPIO_PUPDR_PUPD8_Msk (0x3UL << GPIO_PUPDR_PUPD8_Pos) /*!< 0x00030000 */ #define GPIO_PUPDR_PUPD8 GPIO_PUPDR_PUPD8_Msk #define GPIO_PUPDR_PUPD8_0 (0x1UL << GPIO_PUPDR_PUPD8_Pos) /*!< 0x00010000 */ #define GPIO_PUPDR_PUPD8_1 (0x2UL << GPIO_PUPDR_PUPD8_Pos) /*!< 0x00020000 */ #define GPIO_PUPDR_PUPD9_Pos (18U) #define GPIO_PUPDR_PUPD9_Msk (0x3UL << GPIO_PUPDR_PUPD9_Pos) /*!< 0x000C0000 */ #define GPIO_PUPDR_PUPD9 GPIO_PUPDR_PUPD9_Msk #define GPIO_PUPDR_PUPD9_0 (0x1UL << GPIO_PUPDR_PUPD9_Pos) /*!< 0x00040000 */ #define GPIO_PUPDR_PUPD9_1 (0x2UL << GPIO_PUPDR_PUPD9_Pos) /*!< 0x00080000 */ #define GPIO_PUPDR_PUPD10_Pos (20U) #define GPIO_PUPDR_PUPD10_Msk (0x3UL << GPIO_PUPDR_PUPD10_Pos) /*!< 0x00300000 */ #define GPIO_PUPDR_PUPD10 GPIO_PUPDR_PUPD10_Msk #define GPIO_PUPDR_PUPD10_0 (0x1UL << GPIO_PUPDR_PUPD10_Pos) /*!< 0x00100000 */ #define GPIO_PUPDR_PUPD10_1 (0x2UL << GPIO_PUPDR_PUPD10_Pos) /*!< 0x00200000 */ #define GPIO_PUPDR_PUPD11_Pos (22U) #define GPIO_PUPDR_PUPD11_Msk (0x3UL << GPIO_PUPDR_PUPD11_Pos) /*!< 0x00C00000 */ #define GPIO_PUPDR_PUPD11 GPIO_PUPDR_PUPD11_Msk #define GPIO_PUPDR_PUPD11_0 (0x1UL << GPIO_PUPDR_PUPD11_Pos) /*!< 0x00400000 */ #define GPIO_PUPDR_PUPD11_1 (0x2UL << GPIO_PUPDR_PUPD11_Pos) /*!< 0x00800000 */ #define GPIO_PUPDR_PUPD12_Pos (24U) #define GPIO_PUPDR_PUPD12_Msk (0x3UL << GPIO_PUPDR_PUPD12_Pos) /*!< 0x03000000 */ #define GPIO_PUPDR_PUPD12 GPIO_PUPDR_PUPD12_Msk #define GPIO_PUPDR_PUPD12_0 (0x1UL << GPIO_PUPDR_PUPD12_Pos) /*!< 0x01000000 */ #define GPIO_PUPDR_PUPD12_1 (0x2UL << GPIO_PUPDR_PUPD12_Pos) /*!< 0x02000000 */ #define GPIO_PUPDR_PUPD13_Pos (26U) #define GPIO_PUPDR_PUPD13_Msk (0x3UL << GPIO_PUPDR_PUPD13_Pos) /*!< 0x0C000000 */ #define GPIO_PUPDR_PUPD13 GPIO_PUPDR_PUPD13_Msk #define GPIO_PUPDR_PUPD13_0 (0x1UL << GPIO_PUPDR_PUPD13_Pos) /*!< 0x04000000 */ #define GPIO_PUPDR_PUPD13_1 (0x2UL << GPIO_PUPDR_PUPD13_Pos) /*!< 0x08000000 */ #define GPIO_PUPDR_PUPD14_Pos (28U) #define GPIO_PUPDR_PUPD14_Msk (0x3UL << GPIO_PUPDR_PUPD14_Pos) /*!< 0x30000000 */ #define GPIO_PUPDR_PUPD14 GPIO_PUPDR_PUPD14_Msk #define GPIO_PUPDR_PUPD14_0 (0x1UL << GPIO_PUPDR_PUPD14_Pos) /*!< 0x10000000 */ #define GPIO_PUPDR_PUPD14_1 (0x2UL << GPIO_PUPDR_PUPD14_Pos) /*!< 0x20000000 */ #define GPIO_PUPDR_PUPD15_Pos (30U) #define GPIO_PUPDR_PUPD15_Msk (0x3UL << GPIO_PUPDR_PUPD15_Pos) /*!< 0xC0000000 */ #define GPIO_PUPDR_PUPD15 GPIO_PUPDR_PUPD15_Msk #define GPIO_PUPDR_PUPD15_0 (0x1UL << GPIO_PUPDR_PUPD15_Pos) /*!< 0x40000000 */ #define GPIO_PUPDR_PUPD15_1 (0x2UL << GPIO_PUPDR_PUPD15_Pos) /*!< 0x80000000 */ /****************** Bits definition for GPIO_IDR register *******************/ #define GPIO_IDR_ID0_Pos (0U) #define GPIO_IDR_ID0_Msk (0x1UL << GPIO_IDR_ID0_Pos) /*!< 0x00000001 */ #define GPIO_IDR_ID0 GPIO_IDR_ID0_Msk #define GPIO_IDR_ID1_Pos (1U) #define GPIO_IDR_ID1_Msk (0x1UL << GPIO_IDR_ID1_Pos) /*!< 0x00000002 */ #define GPIO_IDR_ID1 GPIO_IDR_ID1_Msk #define GPIO_IDR_ID2_Pos (2U) #define GPIO_IDR_ID2_Msk (0x1UL << GPIO_IDR_ID2_Pos) /*!< 0x00000004 */ #define GPIO_IDR_ID2 GPIO_IDR_ID2_Msk #define GPIO_IDR_ID3_Pos (3U) #define GPIO_IDR_ID3_Msk (0x1UL << GPIO_IDR_ID3_Pos) /*!< 0x00000008 */ #define GPIO_IDR_ID3 GPIO_IDR_ID3_Msk #define GPIO_IDR_ID4_Pos (4U) #define GPIO_IDR_ID4_Msk (0x1UL << GPIO_IDR_ID4_Pos) /*!< 0x00000010 */ #define GPIO_IDR_ID4 GPIO_IDR_ID4_Msk #define GPIO_IDR_ID5_Pos (5U) #define GPIO_IDR_ID5_Msk (0x1UL << GPIO_IDR_ID5_Pos) /*!< 0x00000020 */ #define GPIO_IDR_ID5 GPIO_IDR_ID5_Msk #define GPIO_IDR_ID6_Pos (6U) #define GPIO_IDR_ID6_Msk (0x1UL << GPIO_IDR_ID6_Pos) /*!< 0x00000040 */ #define GPIO_IDR_ID6 GPIO_IDR_ID6_Msk #define GPIO_IDR_ID7_Pos (7U) #define GPIO_IDR_ID7_Msk (0x1UL << GPIO_IDR_ID7_Pos) /*!< 0x00000080 */ #define GPIO_IDR_ID7 GPIO_IDR_ID7_Msk #define GPIO_IDR_ID8_Pos (8U) #define GPIO_IDR_ID8_Msk (0x1UL << GPIO_IDR_ID8_Pos) /*!< 0x00000100 */ #define GPIO_IDR_ID8 GPIO_IDR_ID8_Msk #define GPIO_IDR_ID9_Pos (9U) #define GPIO_IDR_ID9_Msk (0x1UL << GPIO_IDR_ID9_Pos) /*!< 0x00000200 */ #define GPIO_IDR_ID9 GPIO_IDR_ID9_Msk #define GPIO_IDR_ID10_Pos (10U) #define GPIO_IDR_ID10_Msk (0x1UL << GPIO_IDR_ID10_Pos) /*!< 0x00000400 */ #define GPIO_IDR_ID10 GPIO_IDR_ID10_Msk #define GPIO_IDR_ID11_Pos (11U) #define GPIO_IDR_ID11_Msk (0x1UL << GPIO_IDR_ID11_Pos) /*!< 0x00000800 */ #define GPIO_IDR_ID11 GPIO_IDR_ID11_Msk #define GPIO_IDR_ID12_Pos (12U) #define GPIO_IDR_ID12_Msk (0x1UL << GPIO_IDR_ID12_Pos) /*!< 0x00001000 */ #define GPIO_IDR_ID12 GPIO_IDR_ID12_Msk #define GPIO_IDR_ID13_Pos (13U) #define GPIO_IDR_ID13_Msk (0x1UL << GPIO_IDR_ID13_Pos) /*!< 0x00002000 */ #define GPIO_IDR_ID13 GPIO_IDR_ID13_Msk #define GPIO_IDR_ID14_Pos (14U) #define GPIO_IDR_ID14_Msk (0x1UL << GPIO_IDR_ID14_Pos) /*!< 0x00004000 */ #define GPIO_IDR_ID14 GPIO_IDR_ID14_Msk #define GPIO_IDR_ID15_Pos (15U) #define GPIO_IDR_ID15_Msk (0x1UL << GPIO_IDR_ID15_Pos) /*!< 0x00008000 */ #define GPIO_IDR_ID15 GPIO_IDR_ID15_Msk /****************** Bits definition for GPIO_ODR register *******************/ #define GPIO_ODR_OD0_Pos (0U) #define GPIO_ODR_OD0_Msk (0x1UL << GPIO_ODR_OD0_Pos) /*!< 0x00000001 */ #define GPIO_ODR_OD0 GPIO_ODR_OD0_Msk #define GPIO_ODR_OD1_Pos (1U) #define GPIO_ODR_OD1_Msk (0x1UL << GPIO_ODR_OD1_Pos) /*!< 0x00000002 */ #define GPIO_ODR_OD1 GPIO_ODR_OD1_Msk #define GPIO_ODR_OD2_Pos (2U) #define GPIO_ODR_OD2_Msk (0x1UL << GPIO_ODR_OD2_Pos) /*!< 0x00000004 */ #define GPIO_ODR_OD2 GPIO_ODR_OD2_Msk #define GPIO_ODR_OD3_Pos (3U) #define GPIO_ODR_OD3_Msk (0x1UL << GPIO_ODR_OD3_Pos) /*!< 0x00000008 */ #define GPIO_ODR_OD3 GPIO_ODR_OD3_Msk #define GPIO_ODR_OD4_Pos (4U) #define GPIO_ODR_OD4_Msk (0x1UL << GPIO_ODR_OD4_Pos) /*!< 0x00000010 */ #define GPIO_ODR_OD4 GPIO_ODR_OD4_Msk #define GPIO_ODR_OD5_Pos (5U) #define GPIO_ODR_OD5_Msk (0x1UL << GPIO_ODR_OD5_Pos) /*!< 0x00000020 */ #define GPIO_ODR_OD5 GPIO_ODR_OD5_Msk #define GPIO_ODR_OD6_Pos (6U) #define GPIO_ODR_OD6_Msk (0x1UL << GPIO_ODR_OD6_Pos) /*!< 0x00000040 */ #define GPIO_ODR_OD6 GPIO_ODR_OD6_Msk #define GPIO_ODR_OD7_Pos (7U) #define GPIO_ODR_OD7_Msk (0x1UL << GPIO_ODR_OD7_Pos) /*!< 0x00000080 */ #define GPIO_ODR_OD7 GPIO_ODR_OD7_Msk #define GPIO_ODR_OD8_Pos (8U) #define GPIO_ODR_OD8_Msk (0x1UL << GPIO_ODR_OD8_Pos) /*!< 0x00000100 */ #define GPIO_ODR_OD8 GPIO_ODR_OD8_Msk #define GPIO_ODR_OD9_Pos (9U) #define GPIO_ODR_OD9_Msk (0x1UL << GPIO_ODR_OD9_Pos) /*!< 0x00000200 */ #define GPIO_ODR_OD9 GPIO_ODR_OD9_Msk #define GPIO_ODR_OD10_Pos (10U) #define GPIO_ODR_OD10_Msk (0x1UL << GPIO_ODR_OD10_Pos) /*!< 0x00000400 */ #define GPIO_ODR_OD10 GPIO_ODR_OD10_Msk #define GPIO_ODR_OD11_Pos (11U) #define GPIO_ODR_OD11_Msk (0x1UL << GPIO_ODR_OD11_Pos) /*!< 0x00000800 */ #define GPIO_ODR_OD11 GPIO_ODR_OD11_Msk #define GPIO_ODR_OD12_Pos (12U) #define GPIO_ODR_OD12_Msk (0x1UL << GPIO_ODR_OD12_Pos) /*!< 0x00001000 */ #define GPIO_ODR_OD12 GPIO_ODR_OD12_Msk #define GPIO_ODR_OD13_Pos (13U) #define GPIO_ODR_OD13_Msk (0x1UL << GPIO_ODR_OD13_Pos) /*!< 0x00002000 */ #define GPIO_ODR_OD13 GPIO_ODR_OD13_Msk #define GPIO_ODR_OD14_Pos (14U) #define GPIO_ODR_OD14_Msk (0x1UL << GPIO_ODR_OD14_Pos) /*!< 0x00004000 */ #define GPIO_ODR_OD14 GPIO_ODR_OD14_Msk #define GPIO_ODR_OD15_Pos (15U) #define GPIO_ODR_OD15_Msk (0x1UL << GPIO_ODR_OD15_Pos) /*!< 0x00008000 */ #define GPIO_ODR_OD15 GPIO_ODR_OD15_Msk /****************** Bits definition for GPIO_BSRR register ******************/ #define GPIO_BSRR_BS0_Pos (0U) #define GPIO_BSRR_BS0_Msk (0x1UL << GPIO_BSRR_BS0_Pos) /*!< 0x00000001 */ #define GPIO_BSRR_BS0 GPIO_BSRR_BS0_Msk #define GPIO_BSRR_BS1_Pos (1U) #define GPIO_BSRR_BS1_Msk (0x1UL << GPIO_BSRR_BS1_Pos) /*!< 0x00000002 */ #define GPIO_BSRR_BS1 GPIO_BSRR_BS1_Msk #define GPIO_BSRR_BS2_Pos (2U) #define GPIO_BSRR_BS2_Msk (0x1UL << GPIO_BSRR_BS2_Pos) /*!< 0x00000004 */ #define GPIO_BSRR_BS2 GPIO_BSRR_BS2_Msk #define GPIO_BSRR_BS3_Pos (3U) #define GPIO_BSRR_BS3_Msk (0x1UL << GPIO_BSRR_BS3_Pos) /*!< 0x00000008 */ #define GPIO_BSRR_BS3 GPIO_BSRR_BS3_Msk #define GPIO_BSRR_BS4_Pos (4U) #define GPIO_BSRR_BS4_Msk (0x1UL << GPIO_BSRR_BS4_Pos) /*!< 0x00000010 */ #define GPIO_BSRR_BS4 GPIO_BSRR_BS4_Msk #define GPIO_BSRR_BS5_Pos (5U) #define GPIO_BSRR_BS5_Msk (0x1UL << GPIO_BSRR_BS5_Pos) /*!< 0x00000020 */ #define GPIO_BSRR_BS5 GPIO_BSRR_BS5_Msk #define GPIO_BSRR_BS6_Pos (6U) #define GPIO_BSRR_BS6_Msk (0x1UL << GPIO_BSRR_BS6_Pos) /*!< 0x00000040 */ #define GPIO_BSRR_BS6 GPIO_BSRR_BS6_Msk #define GPIO_BSRR_BS7_Pos (7U) #define GPIO_BSRR_BS7_Msk (0x1UL << GPIO_BSRR_BS7_Pos) /*!< 0x00000080 */ #define GPIO_BSRR_BS7 GPIO_BSRR_BS7_Msk #define GPIO_BSRR_BS8_Pos (8U) #define GPIO_BSRR_BS8_Msk (0x1UL << GPIO_BSRR_BS8_Pos) /*!< 0x00000100 */ #define GPIO_BSRR_BS8 GPIO_BSRR_BS8_Msk #define GPIO_BSRR_BS9_Pos (9U) #define GPIO_BSRR_BS9_Msk (0x1UL << GPIO_BSRR_BS9_Pos) /*!< 0x00000200 */ #define GPIO_BSRR_BS9 GPIO_BSRR_BS9_Msk #define GPIO_BSRR_BS10_Pos (10U) #define GPIO_BSRR_BS10_Msk (0x1UL << GPIO_BSRR_BS10_Pos) /*!< 0x00000400 */ #define GPIO_BSRR_BS10 GPIO_BSRR_BS10_Msk #define GPIO_BSRR_BS11_Pos (11U) #define GPIO_BSRR_BS11_Msk (0x1UL << GPIO_BSRR_BS11_Pos) /*!< 0x00000800 */ #define GPIO_BSRR_BS11 GPIO_BSRR_BS11_Msk #define GPIO_BSRR_BS12_Pos (12U) #define GPIO_BSRR_BS12_Msk (0x1UL << GPIO_BSRR_BS12_Pos) /*!< 0x00001000 */ #define GPIO_BSRR_BS12 GPIO_BSRR_BS12_Msk #define GPIO_BSRR_BS13_Pos (13U) #define GPIO_BSRR_BS13_Msk (0x1UL << GPIO_BSRR_BS13_Pos) /*!< 0x00002000 */ #define GPIO_BSRR_BS13 GPIO_BSRR_BS13_Msk #define GPIO_BSRR_BS14_Pos (14U) #define GPIO_BSRR_BS14_Msk (0x1UL << GPIO_BSRR_BS14_Pos) /*!< 0x00004000 */ #define GPIO_BSRR_BS14 GPIO_BSRR_BS14_Msk #define GPIO_BSRR_BS15_Pos (15U) #define GPIO_BSRR_BS15_Msk (0x1UL << GPIO_BSRR_BS15_Pos) /*!< 0x00008000 */ #define GPIO_BSRR_BS15 GPIO_BSRR_BS15_Msk #define GPIO_BSRR_BR0_Pos (16U) #define GPIO_BSRR_BR0_Msk (0x1UL << GPIO_BSRR_BR0_Pos) /*!< 0x00010000 */ #define GPIO_BSRR_BR0 GPIO_BSRR_BR0_Msk #define GPIO_BSRR_BR1_Pos (17U) #define GPIO_BSRR_BR1_Msk (0x1UL << GPIO_BSRR_BR1_Pos) /*!< 0x00020000 */ #define GPIO_BSRR_BR1 GPIO_BSRR_BR1_Msk #define GPIO_BSRR_BR2_Pos (18U) #define GPIO_BSRR_BR2_Msk (0x1UL << GPIO_BSRR_BR2_Pos) /*!< 0x00040000 */ #define GPIO_BSRR_BR2 GPIO_BSRR_BR2_Msk #define GPIO_BSRR_BR3_Pos (19U) #define GPIO_BSRR_BR3_Msk (0x1UL << GPIO_BSRR_BR3_Pos) /*!< 0x00080000 */ #define GPIO_BSRR_BR3 GPIO_BSRR_BR3_Msk #define GPIO_BSRR_BR4_Pos (20U) #define GPIO_BSRR_BR4_Msk (0x1UL << GPIO_BSRR_BR4_Pos) /*!< 0x00100000 */ #define GPIO_BSRR_BR4 GPIO_BSRR_BR4_Msk #define GPIO_BSRR_BR5_Pos (21U) #define GPIO_BSRR_BR5_Msk (0x1UL << GPIO_BSRR_BR5_Pos) /*!< 0x00200000 */ #define GPIO_BSRR_BR5 GPIO_BSRR_BR5_Msk #define GPIO_BSRR_BR6_Pos (22U) #define GPIO_BSRR_BR6_Msk (0x1UL << GPIO_BSRR_BR6_Pos) /*!< 0x00400000 */ #define GPIO_BSRR_BR6 GPIO_BSRR_BR6_Msk #define GPIO_BSRR_BR7_Pos (23U) #define GPIO_BSRR_BR7_Msk (0x1UL << GPIO_BSRR_BR7_Pos) /*!< 0x00800000 */ #define GPIO_BSRR_BR7 GPIO_BSRR_BR7_Msk #define GPIO_BSRR_BR8_Pos (24U) #define GPIO_BSRR_BR8_Msk (0x1UL << GPIO_BSRR_BR8_Pos) /*!< 0x01000000 */ #define GPIO_BSRR_BR8 GPIO_BSRR_BR8_Msk #define GPIO_BSRR_BR9_Pos (25U) #define GPIO_BSRR_BR9_Msk (0x1UL << GPIO_BSRR_BR9_Pos) /*!< 0x02000000 */ #define GPIO_BSRR_BR9 GPIO_BSRR_BR9_Msk #define GPIO_BSRR_BR10_Pos (26U) #define GPIO_BSRR_BR10_Msk (0x1UL << GPIO_BSRR_BR10_Pos) /*!< 0x04000000 */ #define GPIO_BSRR_BR10 GPIO_BSRR_BR10_Msk #define GPIO_BSRR_BR11_Pos (27U) #define GPIO_BSRR_BR11_Msk (0x1UL << GPIO_BSRR_BR11_Pos) /*!< 0x08000000 */ #define GPIO_BSRR_BR11 GPIO_BSRR_BR11_Msk #define GPIO_BSRR_BR12_Pos (28U) #define GPIO_BSRR_BR12_Msk (0x1UL << GPIO_BSRR_BR12_Pos) /*!< 0x10000000 */ #define GPIO_BSRR_BR12 GPIO_BSRR_BR12_Msk #define GPIO_BSRR_BR13_Pos (29U) #define GPIO_BSRR_BR13_Msk (0x1UL << GPIO_BSRR_BR13_Pos) /*!< 0x20000000 */ #define GPIO_BSRR_BR13 GPIO_BSRR_BR13_Msk #define GPIO_BSRR_BR14_Pos (30U) #define GPIO_BSRR_BR14_Msk (0x1UL << GPIO_BSRR_BR14_Pos) /*!< 0x40000000 */ #define GPIO_BSRR_BR14 GPIO_BSRR_BR14_Msk #define GPIO_BSRR_BR15_Pos (31U) #define GPIO_BSRR_BR15_Msk (0x1UL << GPIO_BSRR_BR15_Pos) /*!< 0x80000000 */ #define GPIO_BSRR_BR15 GPIO_BSRR_BR15_Msk /****************** Bit definition for GPIO_LCKR register *********************/ #define GPIO_LCKR_LCK0_Pos (0U) #define GPIO_LCKR_LCK0_Msk (0x1UL << GPIO_LCKR_LCK0_Pos) /*!< 0x00000001 */ #define GPIO_LCKR_LCK0 GPIO_LCKR_LCK0_Msk #define GPIO_LCKR_LCK1_Pos (1U) #define GPIO_LCKR_LCK1_Msk (0x1UL << GPIO_LCKR_LCK1_Pos) /*!< 0x00000002 */ #define GPIO_LCKR_LCK1 GPIO_LCKR_LCK1_Msk #define GPIO_LCKR_LCK2_Pos (2U) #define GPIO_LCKR_LCK2_Msk (0x1UL << GPIO_LCKR_LCK2_Pos) /*!< 0x00000004 */ #define GPIO_LCKR_LCK2 GPIO_LCKR_LCK2_Msk #define GPIO_LCKR_LCK3_Pos (3U) #define GPIO_LCKR_LCK3_Msk (0x1UL << GPIO_LCKR_LCK3_Pos) /*!< 0x00000008 */ #define GPIO_LCKR_LCK3 GPIO_LCKR_LCK3_Msk #define GPIO_LCKR_LCK4_Pos (4U) #define GPIO_LCKR_LCK4_Msk (0x1UL << GPIO_LCKR_LCK4_Pos) /*!< 0x00000010 */ #define GPIO_LCKR_LCK4 GPIO_LCKR_LCK4_Msk #define GPIO_LCKR_LCK5_Pos (5U) #define GPIO_LCKR_LCK5_Msk (0x1UL << GPIO_LCKR_LCK5_Pos) /*!< 0x00000020 */ #define GPIO_LCKR_LCK5 GPIO_LCKR_LCK5_Msk #define GPIO_LCKR_LCK6_Pos (6U) #define GPIO_LCKR_LCK6_Msk (0x1UL << GPIO_LCKR_LCK6_Pos) /*!< 0x00000040 */ #define GPIO_LCKR_LCK6 GPIO_LCKR_LCK6_Msk #define GPIO_LCKR_LCK7_Pos (7U) #define GPIO_LCKR_LCK7_Msk (0x1UL << GPIO_LCKR_LCK7_Pos) /*!< 0x00000080 */ #define GPIO_LCKR_LCK7 GPIO_LCKR_LCK7_Msk #define GPIO_LCKR_LCK8_Pos (8U) #define GPIO_LCKR_LCK8_Msk (0x1UL << GPIO_LCKR_LCK8_Pos) /*!< 0x00000100 */ #define GPIO_LCKR_LCK8 GPIO_LCKR_LCK8_Msk #define GPIO_LCKR_LCK9_Pos (9U) #define GPIO_LCKR_LCK9_Msk (0x1UL << GPIO_LCKR_LCK9_Pos) /*!< 0x00000200 */ #define GPIO_LCKR_LCK9 GPIO_LCKR_LCK9_Msk #define GPIO_LCKR_LCK10_Pos (10U) #define GPIO_LCKR_LCK10_Msk (0x1UL << GPIO_LCKR_LCK10_Pos) /*!< 0x00000400 */ #define GPIO_LCKR_LCK10 GPIO_LCKR_LCK10_Msk #define GPIO_LCKR_LCK11_Pos (11U) #define GPIO_LCKR_LCK11_Msk (0x1UL << GPIO_LCKR_LCK11_Pos) /*!< 0x00000800 */ #define GPIO_LCKR_LCK11 GPIO_LCKR_LCK11_Msk #define GPIO_LCKR_LCK12_Pos (12U) #define GPIO_LCKR_LCK12_Msk (0x1UL << GPIO_LCKR_LCK12_Pos) /*!< 0x00001000 */ #define GPIO_LCKR_LCK12 GPIO_LCKR_LCK12_Msk #define GPIO_LCKR_LCK13_Pos (13U) #define GPIO_LCKR_LCK13_Msk (0x1UL << GPIO_LCKR_LCK13_Pos) /*!< 0x00002000 */ #define GPIO_LCKR_LCK13 GPIO_LCKR_LCK13_Msk #define GPIO_LCKR_LCK14_Pos (14U) #define GPIO_LCKR_LCK14_Msk (0x1UL << GPIO_LCKR_LCK14_Pos) /*!< 0x00004000 */ #define GPIO_LCKR_LCK14 GPIO_LCKR_LCK14_Msk #define GPIO_LCKR_LCK15_Pos (15U) #define GPIO_LCKR_LCK15_Msk (0x1UL << GPIO_LCKR_LCK15_Pos) /*!< 0x00008000 */ #define GPIO_LCKR_LCK15 GPIO_LCKR_LCK15_Msk #define GPIO_LCKR_LCKK_Pos (16U) #define GPIO_LCKR_LCKK_Msk (0x1UL << GPIO_LCKR_LCKK_Pos) /*!< 0x00010000 */ #define GPIO_LCKR_LCKK GPIO_LCKR_LCKK_Msk /****************** Bit definition for GPIO_AFRL register *********************/ #define GPIO_AFRL_AFSEL0_Pos (0U) #define GPIO_AFRL_AFSEL0_Msk (0xFUL << GPIO_AFRL_AFSEL0_Pos) /*!< 0x0000000F */ #define GPIO_AFRL_AFSEL0 GPIO_AFRL_AFSEL0_Msk #define GPIO_AFRL_AFSEL0_0 (0x1UL << GPIO_AFRL_AFSEL0_Pos) /*!< 0x00000001 */ #define GPIO_AFRL_AFSEL0_1 (0x2UL << GPIO_AFRL_AFSEL0_Pos) /*!< 0x00000002 */ #define GPIO_AFRL_AFSEL0_2 (0x4UL << GPIO_AFRL_AFSEL0_Pos) /*!< 0x00000004 */ #define GPIO_AFRL_AFSEL0_3 (0x8UL << GPIO_AFRL_AFSEL0_Pos) /*!< 0x00000008 */ #define GPIO_AFRL_AFSEL1_Pos (4U) #define GPIO_AFRL_AFSEL1_Msk (0xFUL << GPIO_AFRL_AFSEL1_Pos) /*!< 0x000000F0 */ #define GPIO_AFRL_AFSEL1 GPIO_AFRL_AFSEL1_Msk #define GPIO_AFRL_AFSEL1_0 (0x1UL << GPIO_AFRL_AFSEL1_Pos) /*!< 0x00000010 */ #define GPIO_AFRL_AFSEL1_1 (0x2UL << GPIO_AFRL_AFSEL1_Pos) /*!< 0x00000020 */ #define GPIO_AFRL_AFSEL1_2 (0x4UL << GPIO_AFRL_AFSEL1_Pos) /*!< 0x00000040 */ #define GPIO_AFRL_AFSEL1_3 (0x8UL << GPIO_AFRL_AFSEL1_Pos) /*!< 0x00000080 */ #define GPIO_AFRL_AFSEL2_Pos (8U) #define GPIO_AFRL_AFSEL2_Msk (0xFUL << GPIO_AFRL_AFSEL2_Pos) /*!< 0x00000F00 */ #define GPIO_AFRL_AFSEL2 GPIO_AFRL_AFSEL2_Msk #define GPIO_AFRL_AFSEL2_0 (0x1UL << GPIO_AFRL_AFSEL2_Pos) /*!< 0x00000100 */ #define GPIO_AFRL_AFSEL2_1 (0x2UL << GPIO_AFRL_AFSEL2_Pos) /*!< 0x00000200 */ #define GPIO_AFRL_AFSEL2_2 (0x4UL << GPIO_AFRL_AFSEL2_Pos) /*!< 0x00000400 */ #define GPIO_AFRL_AFSEL2_3 (0x8UL << GPIO_AFRL_AFSEL2_Pos) /*!< 0x00000800 */ #define GPIO_AFRL_AFSEL3_Pos (12U) #define GPIO_AFRL_AFSEL3_Msk (0xFUL << GPIO_AFRL_AFSEL3_Pos) /*!< 0x0000F000 */ #define GPIO_AFRL_AFSEL3 GPIO_AFRL_AFSEL3_Msk #define GPIO_AFRL_AFSEL3_0 (0x1UL << GPIO_AFRL_AFSEL3_Pos) /*!< 0x00001000 */ #define GPIO_AFRL_AFSEL3_1 (0x2UL << GPIO_AFRL_AFSEL3_Pos) /*!< 0x00002000 */ #define GPIO_AFRL_AFSEL3_2 (0x4UL << GPIO_AFRL_AFSEL3_Pos) /*!< 0x00004000 */ #define GPIO_AFRL_AFSEL3_3 (0x8UL << GPIO_AFRL_AFSEL3_Pos) /*!< 0x00008000 */ #define GPIO_AFRL_AFSEL4_Pos (16U) #define GPIO_AFRL_AFSEL4_Msk (0xFUL << GPIO_AFRL_AFSEL4_Pos) /*!< 0x000F0000 */ #define GPIO_AFRL_AFSEL4 GPIO_AFRL_AFSEL4_Msk #define GPIO_AFRL_AFSEL4_0 (0x1UL << GPIO_AFRL_AFSEL4_Pos) /*!< 0x00010000 */ #define GPIO_AFRL_AFSEL4_1 (0x2UL << GPIO_AFRL_AFSEL4_Pos) /*!< 0x00020000 */ #define GPIO_AFRL_AFSEL4_2 (0x4UL << GPIO_AFRL_AFSEL4_Pos) /*!< 0x00040000 */ #define GPIO_AFRL_AFSEL4_3 (0x8UL << GPIO_AFRL_AFSEL4_Pos) /*!< 0x00080000 */ #define GPIO_AFRL_AFSEL5_Pos (20U) #define GPIO_AFRL_AFSEL5_Msk (0xFUL << GPIO_AFRL_AFSEL5_Pos) /*!< 0x00F00000 */ #define GPIO_AFRL_AFSEL5 GPIO_AFRL_AFSEL5_Msk #define GPIO_AFRL_AFSEL5_0 (0x1UL << GPIO_AFRL_AFSEL5_Pos) /*!< 0x00100000 */ #define GPIO_AFRL_AFSEL5_1 (0x2UL << GPIO_AFRL_AFSEL5_Pos) /*!< 0x00200000 */ #define GPIO_AFRL_AFSEL5_2 (0x4UL << GPIO_AFRL_AFSEL5_Pos) /*!< 0x00400000 */ #define GPIO_AFRL_AFSEL5_3 (0x8UL << GPIO_AFRL_AFSEL5_Pos) /*!< 0x00800000 */ #define GPIO_AFRL_AFSEL6_Pos (24U) #define GPIO_AFRL_AFSEL6_Msk (0xFUL << GPIO_AFRL_AFSEL6_Pos) /*!< 0x0F000000 */ #define GPIO_AFRL_AFSEL6 GPIO_AFRL_AFSEL6_Msk #define GPIO_AFRL_AFSEL6_0 (0x1UL << GPIO_AFRL_AFSEL6_Pos) /*!< 0x01000000 */ #define GPIO_AFRL_AFSEL6_1 (0x2UL << GPIO_AFRL_AFSEL6_Pos) /*!< 0x02000000 */ #define GPIO_AFRL_AFSEL6_2 (0x4UL << GPIO_AFRL_AFSEL6_Pos) /*!< 0x04000000 */ #define GPIO_AFRL_AFSEL6_3 (0x8UL << GPIO_AFRL_AFSEL6_Pos) /*!< 0x08000000 */ #define GPIO_AFRL_AFSEL7_Pos (28U) #define GPIO_AFRL_AFSEL7_Msk (0xFUL << GPIO_AFRL_AFSEL7_Pos) /*!< 0xF0000000 */ #define GPIO_AFRL_AFSEL7 GPIO_AFRL_AFSEL7_Msk #define GPIO_AFRL_AFSEL7_0 (0x1UL << GPIO_AFRL_AFSEL7_Pos) /*!< 0x10000000 */ #define GPIO_AFRL_AFSEL7_1 (0x2UL << GPIO_AFRL_AFSEL7_Pos) /*!< 0x20000000 */ #define GPIO_AFRL_AFSEL7_2 (0x4UL << GPIO_AFRL_AFSEL7_Pos) /*!< 0x40000000 */ #define GPIO_AFRL_AFSEL7_3 (0x8UL << GPIO_AFRL_AFSEL7_Pos) /*!< 0x80000000 */ /****************** Bit definition for GPIO_AFRH register *********************/ #define GPIO_AFRH_AFSEL8_Pos (0U) #define GPIO_AFRH_AFSEL8_Msk (0xFUL << GPIO_AFRH_AFSEL8_Pos) /*!< 0x0000000F */ #define GPIO_AFRH_AFSEL8 GPIO_AFRH_AFSEL8_Msk #define GPIO_AFRH_AFSEL8_0 (0x1UL << GPIO_AFRH_AFSEL8_Pos) /*!< 0x00000001 */ #define GPIO_AFRH_AFSEL8_1 (0x2UL << GPIO_AFRH_AFSEL8_Pos) /*!< 0x00000002 */ #define GPIO_AFRH_AFSEL8_2 (0x4UL << GPIO_AFRH_AFSEL8_Pos) /*!< 0x00000004 */ #define GPIO_AFRH_AFSEL8_3 (0x8UL << GPIO_AFRH_AFSEL8_Pos) /*!< 0x00000008 */ #define GPIO_AFRH_AFSEL9_Pos (4U) #define GPIO_AFRH_AFSEL9_Msk (0xFUL << GPIO_AFRH_AFSEL9_Pos) /*!< 0x000000F0 */ #define GPIO_AFRH_AFSEL9 GPIO_AFRH_AFSEL9_Msk #define GPIO_AFRH_AFSEL9_0 (0x1UL << GPIO_AFRH_AFSEL9_Pos) /*!< 0x00000010 */ #define GPIO_AFRH_AFSEL9_1 (0x2UL << GPIO_AFRH_AFSEL9_Pos) /*!< 0x00000020 */ #define GPIO_AFRH_AFSEL9_2 (0x4UL << GPIO_AFRH_AFSEL9_Pos) /*!< 0x00000040 */ #define GPIO_AFRH_AFSEL9_3 (0x8UL << GPIO_AFRH_AFSEL9_Pos) /*!< 0x00000080 */ #define GPIO_AFRH_AFSEL10_Pos (8U) #define GPIO_AFRH_AFSEL10_Msk (0xFUL << GPIO_AFRH_AFSEL10_Pos) /*!< 0x00000F00 */ #define GPIO_AFRH_AFSEL10 GPIO_AFRH_AFSEL10_Msk #define GPIO_AFRH_AFSEL10_0 (0x1UL << GPIO_AFRH_AFSEL10_Pos) /*!< 0x00000100 */ #define GPIO_AFRH_AFSEL10_1 (0x2UL << GPIO_AFRH_AFSEL10_Pos) /*!< 0x00000200 */ #define GPIO_AFRH_AFSEL10_2 (0x4UL << GPIO_AFRH_AFSEL10_Pos) /*!< 0x00000400 */ #define GPIO_AFRH_AFSEL10_3 (0x8UL << GPIO_AFRH_AFSEL10_Pos) /*!< 0x00000800 */ #define GPIO_AFRH_AFSEL11_Pos (12U) #define GPIO_AFRH_AFSEL11_Msk (0xFUL << GPIO_AFRH_AFSEL11_Pos) /*!< 0x0000F000 */ #define GPIO_AFRH_AFSEL11 GPIO_AFRH_AFSEL11_Msk #define GPIO_AFRH_AFSEL11_0 (0x1UL << GPIO_AFRH_AFSEL11_Pos) /*!< 0x00001000 */ #define GPIO_AFRH_AFSEL11_1 (0x2UL << GPIO_AFRH_AFSEL11_Pos) /*!< 0x00002000 */ #define GPIO_AFRH_AFSEL11_2 (0x4UL << GPIO_AFRH_AFSEL11_Pos) /*!< 0x00004000 */ #define GPIO_AFRH_AFSEL11_3 (0x8UL << GPIO_AFRH_AFSEL11_Pos) /*!< 0x00008000 */ #define GPIO_AFRH_AFSEL12_Pos (16U) #define GPIO_AFRH_AFSEL12_Msk (0xFUL << GPIO_AFRH_AFSEL12_Pos) /*!< 0x000F0000 */ #define GPIO_AFRH_AFSEL12 GPIO_AFRH_AFSEL12_Msk #define GPIO_AFRH_AFSEL12_0 (0x1UL << GPIO_AFRH_AFSEL12_Pos) /*!< 0x00010000 */ #define GPIO_AFRH_AFSEL12_1 (0x2UL << GPIO_AFRH_AFSEL12_Pos) /*!< 0x00020000 */ #define GPIO_AFRH_AFSEL12_2 (0x4UL << GPIO_AFRH_AFSEL12_Pos) /*!< 0x00040000 */ #define GPIO_AFRH_AFSEL12_3 (0x8UL << GPIO_AFRH_AFSEL12_Pos) /*!< 0x00080000 */ #define GPIO_AFRH_AFSEL13_Pos (20U) #define GPIO_AFRH_AFSEL13_Msk (0xFUL << GPIO_AFRH_AFSEL13_Pos) /*!< 0x00F00000 */ #define GPIO_AFRH_AFSEL13 GPIO_AFRH_AFSEL13_Msk #define GPIO_AFRH_AFSEL13_0 (0x1UL << GPIO_AFRH_AFSEL13_Pos) /*!< 0x00100000 */ #define GPIO_AFRH_AFSEL13_1 (0x2UL << GPIO_AFRH_AFSEL13_Pos) /*!< 0x00200000 */ #define GPIO_AFRH_AFSEL13_2 (0x4UL << GPIO_AFRH_AFSEL13_Pos) /*!< 0x00400000 */ #define GPIO_AFRH_AFSEL13_3 (0x8UL << GPIO_AFRH_AFSEL13_Pos) /*!< 0x00800000 */ #define GPIO_AFRH_AFSEL14_Pos (24U) #define GPIO_AFRH_AFSEL14_Msk (0xFUL << GPIO_AFRH_AFSEL14_Pos) /*!< 0x0F000000 */ #define GPIO_AFRH_AFSEL14 GPIO_AFRH_AFSEL14_Msk #define GPIO_AFRH_AFSEL14_0 (0x1UL << GPIO_AFRH_AFSEL14_Pos) /*!< 0x01000000 */ #define GPIO_AFRH_AFSEL14_1 (0x2UL << GPIO_AFRH_AFSEL14_Pos) /*!< 0x02000000 */ #define GPIO_AFRH_AFSEL14_2 (0x4UL << GPIO_AFRH_AFSEL14_Pos) /*!< 0x04000000 */ #define GPIO_AFRH_AFSEL14_3 (0x8UL << GPIO_AFRH_AFSEL14_Pos) /*!< 0x08000000 */ #define GPIO_AFRH_AFSEL15_Pos (28U) #define GPIO_AFRH_AFSEL15_Msk (0xFUL << GPIO_AFRH_AFSEL15_Pos) /*!< 0xF0000000 */ #define GPIO_AFRH_AFSEL15 GPIO_AFRH_AFSEL15_Msk #define GPIO_AFRH_AFSEL15_0 (0x1UL << GPIO_AFRH_AFSEL15_Pos) /*!< 0x10000000 */ #define GPIO_AFRH_AFSEL15_1 (0x2UL << GPIO_AFRH_AFSEL15_Pos) /*!< 0x20000000 */ #define GPIO_AFRH_AFSEL15_2 (0x4UL << GPIO_AFRH_AFSEL15_Pos) /*!< 0x40000000 */ #define GPIO_AFRH_AFSEL15_3 (0x8UL << GPIO_AFRH_AFSEL15_Pos) /*!< 0x80000000 */ /****************** Bits definition for GPIO_BRR register ******************/ #define GPIO_BRR_BR0_Pos (0U) #define GPIO_BRR_BR0_Msk (0x1UL << GPIO_BRR_BR0_Pos) /*!< 0x00000001 */ #define GPIO_BRR_BR0 GPIO_BRR_BR0_Msk #define GPIO_BRR_BR1_Pos (1U) #define GPIO_BRR_BR1_Msk (0x1UL << GPIO_BRR_BR1_Pos) /*!< 0x00000002 */ #define GPIO_BRR_BR1 GPIO_BRR_BR1_Msk #define GPIO_BRR_BR2_Pos (2U) #define GPIO_BRR_BR2_Msk (0x1UL << GPIO_BRR_BR2_Pos) /*!< 0x00000004 */ #define GPIO_BRR_BR2 GPIO_BRR_BR2_Msk #define GPIO_BRR_BR3_Pos (3U) #define GPIO_BRR_BR3_Msk (0x1UL << GPIO_BRR_BR3_Pos) /*!< 0x00000008 */ #define GPIO_BRR_BR3 GPIO_BRR_BR3_Msk #define GPIO_BRR_BR4_Pos (4U) #define GPIO_BRR_BR4_Msk (0x1UL << GPIO_BRR_BR4_Pos) /*!< 0x00000010 */ #define GPIO_BRR_BR4 GPIO_BRR_BR4_Msk #define GPIO_BRR_BR5_Pos (5U) #define GPIO_BRR_BR5_Msk (0x1UL << GPIO_BRR_BR5_Pos) /*!< 0x00000020 */ #define GPIO_BRR_BR5 GPIO_BRR_BR5_Msk #define GPIO_BRR_BR6_Pos (6U) #define GPIO_BRR_BR6_Msk (0x1UL << GPIO_BRR_BR6_Pos) /*!< 0x00000040 */ #define GPIO_BRR_BR6 GPIO_BRR_BR6_Msk #define GPIO_BRR_BR7_Pos (7U) #define GPIO_BRR_BR7_Msk (0x1UL << GPIO_BRR_BR7_Pos) /*!< 0x00000080 */ #define GPIO_BRR_BR7 GPIO_BRR_BR7_Msk #define GPIO_BRR_BR8_Pos (8U) #define GPIO_BRR_BR8_Msk (0x1UL << GPIO_BRR_BR8_Pos) /*!< 0x00000100 */ #define GPIO_BRR_BR8 GPIO_BRR_BR8_Msk #define GPIO_BRR_BR9_Pos (9U) #define GPIO_BRR_BR9_Msk (0x1UL << GPIO_BRR_BR9_Pos) /*!< 0x00000200 */ #define GPIO_BRR_BR9 GPIO_BRR_BR9_Msk #define GPIO_BRR_BR10_Pos (10U) #define GPIO_BRR_BR10_Msk (0x1UL << GPIO_BRR_BR10_Pos) /*!< 0x00000400 */ #define GPIO_BRR_BR10 GPIO_BRR_BR10_Msk #define GPIO_BRR_BR11_Pos (11U) #define GPIO_BRR_BR11_Msk (0x1UL << GPIO_BRR_BR11_Pos) /*!< 0x00000800 */ #define GPIO_BRR_BR11 GPIO_BRR_BR11_Msk #define GPIO_BRR_BR12_Pos (12U) #define GPIO_BRR_BR12_Msk (0x1UL << GPIO_BRR_BR12_Pos) /*!< 0x00001000 */ #define GPIO_BRR_BR12 GPIO_BRR_BR12_Msk #define GPIO_BRR_BR13_Pos (13U) #define GPIO_BRR_BR13_Msk (0x1UL << GPIO_BRR_BR13_Pos) /*!< 0x00002000 */ #define GPIO_BRR_BR13 GPIO_BRR_BR13_Msk #define GPIO_BRR_BR14_Pos (14U) #define GPIO_BRR_BR14_Msk (0x1UL << GPIO_BRR_BR14_Pos) /*!< 0x00004000 */ #define GPIO_BRR_BR14 GPIO_BRR_BR14_Msk #define GPIO_BRR_BR15_Pos (15U) #define GPIO_BRR_BR15_Msk (0x1UL << GPIO_BRR_BR15_Pos) /*!< 0x00008000 */ #define GPIO_BRR_BR15 GPIO_BRR_BR15_Msk /******************************************************************************/ /* */ /* Inter-integrated Circuit Interface (I2C) */ /* */ /******************************************************************************/ /******************* Bit definition for I2C_CR1 register *******************/ #define I2C_CR1_PE_Pos (0U) #define I2C_CR1_PE_Msk (0x1UL << I2C_CR1_PE_Pos) /*!< 0x00000001 */ #define I2C_CR1_PE I2C_CR1_PE_Msk /*!< Peripheral enable */ #define I2C_CR1_TXIE_Pos (1U) #define I2C_CR1_TXIE_Msk (0x1UL << I2C_CR1_TXIE_Pos) /*!< 0x00000002 */ #define I2C_CR1_TXIE I2C_CR1_TXIE_Msk /*!< TX interrupt enable */ #define I2C_CR1_RXIE_Pos (2U) #define I2C_CR1_RXIE_Msk (0x1UL << I2C_CR1_RXIE_Pos) /*!< 0x00000004 */ #define I2C_CR1_RXIE I2C_CR1_RXIE_Msk /*!< RX interrupt enable */ #define I2C_CR1_ADDRIE_Pos (3U) #define I2C_CR1_ADDRIE_Msk (0x1UL << I2C_CR1_ADDRIE_Pos) /*!< 0x00000008 */ #define I2C_CR1_ADDRIE I2C_CR1_ADDRIE_Msk /*!< Address match interrupt enable */ #define I2C_CR1_NACKIE_Pos (4U) #define I2C_CR1_NACKIE_Msk (0x1UL << I2C_CR1_NACKIE_Pos) /*!< 0x00000010 */ #define I2C_CR1_NACKIE I2C_CR1_NACKIE_Msk /*!< NACK received interrupt enable */ #define I2C_CR1_STOPIE_Pos (5U) #define I2C_CR1_STOPIE_Msk (0x1UL << I2C_CR1_STOPIE_Pos) /*!< 0x00000020 */ #define I2C_CR1_STOPIE I2C_CR1_STOPIE_Msk /*!< STOP detection interrupt enable */ #define I2C_CR1_TCIE_Pos (6U) #define I2C_CR1_TCIE_Msk (0x1UL << I2C_CR1_TCIE_Pos) /*!< 0x00000040 */ #define I2C_CR1_TCIE I2C_CR1_TCIE_Msk /*!< Transfer complete interrupt enable */ #define I2C_CR1_ERRIE_Pos (7U) #define I2C_CR1_ERRIE_Msk (0x1UL << I2C_CR1_ERRIE_Pos) /*!< 0x00000080 */ #define I2C_CR1_ERRIE I2C_CR1_ERRIE_Msk /*!< Errors interrupt enable */ #define I2C_CR1_DNF_Pos (8U) #define I2C_CR1_DNF_Msk (0xFUL << I2C_CR1_DNF_Pos) /*!< 0x00000F00 */ #define I2C_CR1_DNF I2C_CR1_DNF_Msk /*!< Digital noise filter */ #define I2C_CR1_ANFOFF_Pos (12U) #define I2C_CR1_ANFOFF_Msk (0x1UL << I2C_CR1_ANFOFF_Pos) /*!< 0x00001000 */ #define I2C_CR1_ANFOFF I2C_CR1_ANFOFF_Msk /*!< Analog noise filter OFF */ #define I2C_CR1_SWRST_Pos (13U) #define I2C_CR1_SWRST_Msk (0x1UL << I2C_CR1_SWRST_Pos) /*!< 0x00002000 */ #define I2C_CR1_SWRST I2C_CR1_SWRST_Msk /*!< Software reset */ #define I2C_CR1_TXDMAEN_Pos (14U) #define I2C_CR1_TXDMAEN_Msk (0x1UL << I2C_CR1_TXDMAEN_Pos) /*!< 0x00004000 */ #define I2C_CR1_TXDMAEN I2C_CR1_TXDMAEN_Msk /*!< DMA transmission requests enable */ #define I2C_CR1_RXDMAEN_Pos (15U) #define I2C_CR1_RXDMAEN_Msk (0x1UL << I2C_CR1_RXDMAEN_Pos) /*!< 0x00008000 */ #define I2C_CR1_RXDMAEN I2C_CR1_RXDMAEN_Msk /*!< DMA reception requests enable */ #define I2C_CR1_SBC_Pos (16U) #define I2C_CR1_SBC_Msk (0x1UL << I2C_CR1_SBC_Pos) /*!< 0x00010000 */ #define I2C_CR1_SBC I2C_CR1_SBC_Msk /*!< Slave byte control */ #define I2C_CR1_NOSTRETCH_Pos (17U) #define I2C_CR1_NOSTRETCH_Msk (0x1UL << I2C_CR1_NOSTRETCH_Pos) /*!< 0x00020000 */ #define I2C_CR1_NOSTRETCH I2C_CR1_NOSTRETCH_Msk /*!< Clock stretching disable */ #define I2C_CR1_WUPEN_Pos (18U) #define I2C_CR1_WUPEN_Msk (0x1UL << I2C_CR1_WUPEN_Pos) /*!< 0x00040000 */ #define I2C_CR1_WUPEN I2C_CR1_WUPEN_Msk /*!< Wakeup from STOP enable */ #define I2C_CR1_GCEN_Pos (19U) #define I2C_CR1_GCEN_Msk (0x1UL << I2C_CR1_GCEN_Pos) /*!< 0x00080000 */ #define I2C_CR1_GCEN I2C_CR1_GCEN_Msk /*!< General call enable */ #define I2C_CR1_SMBHEN_Pos (20U) #define I2C_CR1_SMBHEN_Msk (0x1UL << I2C_CR1_SMBHEN_Pos) /*!< 0x00100000 */ #define I2C_CR1_SMBHEN I2C_CR1_SMBHEN_Msk /*!< SMBus host address enable */ #define I2C_CR1_SMBDEN_Pos (21U) #define I2C_CR1_SMBDEN_Msk (0x1UL << I2C_CR1_SMBDEN_Pos) /*!< 0x00200000 */ #define I2C_CR1_SMBDEN I2C_CR1_SMBDEN_Msk /*!< SMBus device default address enable */ #define I2C_CR1_ALERTEN_Pos (22U) #define I2C_CR1_ALERTEN_Msk (0x1UL << I2C_CR1_ALERTEN_Pos) /*!< 0x00400000 */ #define I2C_CR1_ALERTEN I2C_CR1_ALERTEN_Msk /*!< SMBus alert enable */ #define I2C_CR1_PECEN_Pos (23U) #define I2C_CR1_PECEN_Msk (0x1UL << I2C_CR1_PECEN_Pos) /*!< 0x00800000 */ #define I2C_CR1_PECEN I2C_CR1_PECEN_Msk /*!< PEC enable */ /****************** Bit definition for I2C_CR2 register ********************/ #define I2C_CR2_SADD_Pos (0U) #define I2C_CR2_SADD_Msk (0x3FFUL << I2C_CR2_SADD_Pos) /*!< 0x000003FF */ #define I2C_CR2_SADD I2C_CR2_SADD_Msk /*!< Slave address (master mode) */ #define I2C_CR2_RD_WRN_Pos (10U) #define I2C_CR2_RD_WRN_Msk (0x1UL << I2C_CR2_RD_WRN_Pos) /*!< 0x00000400 */ #define I2C_CR2_RD_WRN I2C_CR2_RD_WRN_Msk /*!< Transfer direction (master mode) */ #define I2C_CR2_ADD10_Pos (11U) #define I2C_CR2_ADD10_Msk (0x1UL << I2C_CR2_ADD10_Pos) /*!< 0x00000800 */ #define I2C_CR2_ADD10 I2C_CR2_ADD10_Msk /*!< 10-bit addressing mode (master mode) */ #define I2C_CR2_HEAD10R_Pos (12U) #define I2C_CR2_HEAD10R_Msk (0x1UL << I2C_CR2_HEAD10R_Pos) /*!< 0x00001000 */ #define I2C_CR2_HEAD10R I2C_CR2_HEAD10R_Msk /*!< 10-bit address header only read direction (master mode) */ #define I2C_CR2_START_Pos (13U) #define I2C_CR2_START_Msk (0x1UL << I2C_CR2_START_Pos) /*!< 0x00002000 */ #define I2C_CR2_START I2C_CR2_START_Msk /*!< START generation */ #define I2C_CR2_STOP_Pos (14U) #define I2C_CR2_STOP_Msk (0x1UL << I2C_CR2_STOP_Pos) /*!< 0x00004000 */ #define I2C_CR2_STOP I2C_CR2_STOP_Msk /*!< STOP generation (master mode) */ #define I2C_CR2_NACK_Pos (15U) #define I2C_CR2_NACK_Msk (0x1UL << I2C_CR2_NACK_Pos) /*!< 0x00008000 */ #define I2C_CR2_NACK I2C_CR2_NACK_Msk /*!< NACK generation (slave mode) */ #define I2C_CR2_NBYTES_Pos (16U) #define I2C_CR2_NBYTES_Msk (0xFFUL << I2C_CR2_NBYTES_Pos) /*!< 0x00FF0000 */ #define I2C_CR2_NBYTES I2C_CR2_NBYTES_Msk /*!< Number of bytes */ #define I2C_CR2_RELOAD_Pos (24U) #define I2C_CR2_RELOAD_Msk (0x1UL << I2C_CR2_RELOAD_Pos) /*!< 0x01000000 */ #define I2C_CR2_RELOAD I2C_CR2_RELOAD_Msk /*!< NBYTES reload mode */ #define I2C_CR2_AUTOEND_Pos (25U) #define I2C_CR2_AUTOEND_Msk (0x1UL << I2C_CR2_AUTOEND_Pos) /*!< 0x02000000 */ #define I2C_CR2_AUTOEND I2C_CR2_AUTOEND_Msk /*!< Automatic end mode (master mode) */ #define I2C_CR2_PECBYTE_Pos (26U) #define I2C_CR2_PECBYTE_Msk (0x1UL << I2C_CR2_PECBYTE_Pos) /*!< 0x04000000 */ #define I2C_CR2_PECBYTE I2C_CR2_PECBYTE_Msk /*!< Packet error checking byte */ /******************* Bit definition for I2C_OAR1 register ******************/ #define I2C_OAR1_OA1_Pos (0U) #define I2C_OAR1_OA1_Msk (0x3FFUL << I2C_OAR1_OA1_Pos) /*!< 0x000003FF */ #define I2C_OAR1_OA1 I2C_OAR1_OA1_Msk /*!< Interface own address 1 */ #define I2C_OAR1_OA1MODE_Pos (10U) #define I2C_OAR1_OA1MODE_Msk (0x1UL << I2C_OAR1_OA1MODE_Pos) /*!< 0x00000400 */ #define I2C_OAR1_OA1MODE I2C_OAR1_OA1MODE_Msk /*!< Own address 1 10-bit mode */ #define I2C_OAR1_OA1EN_Pos (15U) #define I2C_OAR1_OA1EN_Msk (0x1UL << I2C_OAR1_OA1EN_Pos) /*!< 0x00008000 */ #define I2C_OAR1_OA1EN I2C_OAR1_OA1EN_Msk /*!< Own address 1 enable */ /******************* Bit definition for I2C_OAR2 register ******************/ #define I2C_OAR2_OA2_Pos (1U) #define I2C_OAR2_OA2_Msk (0x7FUL << I2C_OAR2_OA2_Pos) /*!< 0x000000FE */ #define I2C_OAR2_OA2 I2C_OAR2_OA2_Msk /*!< Interface own address 2 */ #define I2C_OAR2_OA2MSK_Pos (8U) #define I2C_OAR2_OA2MSK_Msk (0x7UL << I2C_OAR2_OA2MSK_Pos) /*!< 0x00000700 */ #define I2C_OAR2_OA2MSK I2C_OAR2_OA2MSK_Msk /*!< Own address 2 masks */ #define I2C_OAR2_OA2NOMASK (0U) /*!< No mask */ #define I2C_OAR2_OA2MASK01_Pos (8U) #define I2C_OAR2_OA2MASK01_Msk (0x1UL << I2C_OAR2_OA2MASK01_Pos) /*!< 0x00000100 */ #define I2C_OAR2_OA2MASK01 I2C_OAR2_OA2MASK01_Msk /*!< OA2[1] is masked, Only OA2[7:2] are compared */ #define I2C_OAR2_OA2MASK02_Pos (9U) #define I2C_OAR2_OA2MASK02_Msk (0x1UL << I2C_OAR2_OA2MASK02_Pos) /*!< 0x00000200 */ #define I2C_OAR2_OA2MASK02 I2C_OAR2_OA2MASK02_Msk /*!< OA2[2:1] is masked, Only OA2[7:3] are compared */ #define I2C_OAR2_OA2MASK03_Pos (8U) #define I2C_OAR2_OA2MASK03_Msk (0x3UL << I2C_OAR2_OA2MASK03_Pos) /*!< 0x00000300 */ #define I2C_OAR2_OA2MASK03 I2C_OAR2_OA2MASK03_Msk /*!< OA2[3:1] is masked, Only OA2[7:4] are compared */ #define I2C_OAR2_OA2MASK04_Pos (10U) #define I2C_OAR2_OA2MASK04_Msk (0x1UL << I2C_OAR2_OA2MASK04_Pos) /*!< 0x00000400 */ #define I2C_OAR2_OA2MASK04 I2C_OAR2_OA2MASK04_Msk /*!< OA2[4:1] is masked, Only OA2[7:5] are compared */ #define I2C_OAR2_OA2MASK05_Pos (8U) #define I2C_OAR2_OA2MASK05_Msk (0x5UL << I2C_OAR2_OA2MASK05_Pos) /*!< 0x00000500 */ #define I2C_OAR2_OA2MASK05 I2C_OAR2_OA2MASK05_Msk /*!< OA2[5:1] is masked, Only OA2[7:6] are compared */ #define I2C_OAR2_OA2MASK06_Pos (9U) #define I2C_OAR2_OA2MASK06_Msk (0x3UL << I2C_OAR2_OA2MASK06_Pos) /*!< 0x00000600 */ #define I2C_OAR2_OA2MASK06 I2C_OAR2_OA2MASK06_Msk /*!< OA2[6:1] is masked, Only OA2[7] are compared */ #define I2C_OAR2_OA2MASK07_Pos (8U) #define I2C_OAR2_OA2MASK07_Msk (0x7UL << I2C_OAR2_OA2MASK07_Pos) /*!< 0x00000700 */ #define I2C_OAR2_OA2MASK07 I2C_OAR2_OA2MASK07_Msk /*!< OA2[7:1] is masked, No comparison is done */ #define I2C_OAR2_OA2EN_Pos (15U) #define I2C_OAR2_OA2EN_Msk (0x1UL << I2C_OAR2_OA2EN_Pos) /*!< 0x00008000 */ #define I2C_OAR2_OA2EN I2C_OAR2_OA2EN_Msk /*!< Own address 2 enable */ /******************* Bit definition for I2C_TIMINGR register *******************/ #define I2C_TIMINGR_SCLL_Pos (0U) #define I2C_TIMINGR_SCLL_Msk (0xFFUL << I2C_TIMINGR_SCLL_Pos) /*!< 0x000000FF */ #define I2C_TIMINGR_SCLL I2C_TIMINGR_SCLL_Msk /*!< SCL low period (master mode) */ #define I2C_TIMINGR_SCLH_Pos (8U) #define I2C_TIMINGR_SCLH_Msk (0xFFUL << I2C_TIMINGR_SCLH_Pos) /*!< 0x0000FF00 */ #define I2C_TIMINGR_SCLH I2C_TIMINGR_SCLH_Msk /*!< SCL high period (master mode) */ #define I2C_TIMINGR_SDADEL_Pos (16U) #define I2C_TIMINGR_SDADEL_Msk (0xFUL << I2C_TIMINGR_SDADEL_Pos) /*!< 0x000F0000 */ #define I2C_TIMINGR_SDADEL I2C_TIMINGR_SDADEL_Msk /*!< Data hold time */ #define I2C_TIMINGR_SCLDEL_Pos (20U) #define I2C_TIMINGR_SCLDEL_Msk (0xFUL << I2C_TIMINGR_SCLDEL_Pos) /*!< 0x00F00000 */ #define I2C_TIMINGR_SCLDEL I2C_TIMINGR_SCLDEL_Msk /*!< Data setup time */ #define I2C_TIMINGR_PRESC_Pos (28U) #define I2C_TIMINGR_PRESC_Msk (0xFUL << I2C_TIMINGR_PRESC_Pos) /*!< 0xF0000000 */ #define I2C_TIMINGR_PRESC I2C_TIMINGR_PRESC_Msk /*!< Timings prescaler */ /******************* Bit definition for I2C_TIMEOUTR register *******************/ #define I2C_TIMEOUTR_TIMEOUTA_Pos (0U) #define I2C_TIMEOUTR_TIMEOUTA_Msk (0xFFFUL << I2C_TIMEOUTR_TIMEOUTA_Pos) /*!< 0x00000FFF */ #define I2C_TIMEOUTR_TIMEOUTA I2C_TIMEOUTR_TIMEOUTA_Msk /*!< Bus timeout A */ #define I2C_TIMEOUTR_TIDLE_Pos (12U) #define I2C_TIMEOUTR_TIDLE_Msk (0x1UL << I2C_TIMEOUTR_TIDLE_Pos) /*!< 0x00001000 */ #define I2C_TIMEOUTR_TIDLE I2C_TIMEOUTR_TIDLE_Msk /*!< Idle clock timeout detection */ #define I2C_TIMEOUTR_TIMOUTEN_Pos (15U) #define I2C_TIMEOUTR_TIMOUTEN_Msk (0x1UL << I2C_TIMEOUTR_TIMOUTEN_Pos) /*!< 0x00008000 */ #define I2C_TIMEOUTR_TIMOUTEN I2C_TIMEOUTR_TIMOUTEN_Msk /*!< Clock timeout enable */ #define I2C_TIMEOUTR_TIMEOUTB_Pos (16U) #define I2C_TIMEOUTR_TIMEOUTB_Msk (0xFFFUL << I2C_TIMEOUTR_TIMEOUTB_Pos) /*!< 0x0FFF0000 */ #define I2C_TIMEOUTR_TIMEOUTB I2C_TIMEOUTR_TIMEOUTB_Msk /*!< Bus timeout B*/ #define I2C_TIMEOUTR_TEXTEN_Pos (31U) #define I2C_TIMEOUTR_TEXTEN_Msk (0x1UL << I2C_TIMEOUTR_TEXTEN_Pos) /*!< 0x80000000 */ #define I2C_TIMEOUTR_TEXTEN I2C_TIMEOUTR_TEXTEN_Msk /*!< Extended clock timeout enable */ /****************** Bit definition for I2C_ISR register *********************/ #define I2C_ISR_TXE_Pos (0U) #define I2C_ISR_TXE_Msk (0x1UL << I2C_ISR_TXE_Pos) /*!< 0x00000001 */ #define I2C_ISR_TXE I2C_ISR_TXE_Msk /*!< Transmit data register empty */ #define I2C_ISR_TXIS_Pos (1U) #define I2C_ISR_TXIS_Msk (0x1UL << I2C_ISR_TXIS_Pos) /*!< 0x00000002 */ #define I2C_ISR_TXIS I2C_ISR_TXIS_Msk /*!< Transmit interrupt status */ #define I2C_ISR_RXNE_Pos (2U) #define I2C_ISR_RXNE_Msk (0x1UL << I2C_ISR_RXNE_Pos) /*!< 0x00000004 */ #define I2C_ISR_RXNE I2C_ISR_RXNE_Msk /*!< Receive data register not empty */ #define I2C_ISR_ADDR_Pos (3U) #define I2C_ISR_ADDR_Msk (0x1UL << I2C_ISR_ADDR_Pos) /*!< 0x00000008 */ #define I2C_ISR_ADDR I2C_ISR_ADDR_Msk /*!< Address matched (slave mode)*/ #define I2C_ISR_NACKF_Pos (4U) #define I2C_ISR_NACKF_Msk (0x1UL << I2C_ISR_NACKF_Pos) /*!< 0x00000010 */ #define I2C_ISR_NACKF I2C_ISR_NACKF_Msk /*!< NACK received flag */ #define I2C_ISR_STOPF_Pos (5U) #define I2C_ISR_STOPF_Msk (0x1UL << I2C_ISR_STOPF_Pos) /*!< 0x00000020 */ #define I2C_ISR_STOPF I2C_ISR_STOPF_Msk /*!< STOP detection flag */ #define I2C_ISR_TC_Pos (6U) #define I2C_ISR_TC_Msk (0x1UL << I2C_ISR_TC_Pos) /*!< 0x00000040 */ #define I2C_ISR_TC I2C_ISR_TC_Msk /*!< Transfer complete (master mode) */ #define I2C_ISR_TCR_Pos (7U) #define I2C_ISR_TCR_Msk (0x1UL << I2C_ISR_TCR_Pos) /*!< 0x00000080 */ #define I2C_ISR_TCR I2C_ISR_TCR_Msk /*!< Transfer complete reload */ #define I2C_ISR_BERR_Pos (8U) #define I2C_ISR_BERR_Msk (0x1UL << I2C_ISR_BERR_Pos) /*!< 0x00000100 */ #define I2C_ISR_BERR I2C_ISR_BERR_Msk /*!< Bus error */ #define I2C_ISR_ARLO_Pos (9U) #define I2C_ISR_ARLO_Msk (0x1UL << I2C_ISR_ARLO_Pos) /*!< 0x00000200 */ #define I2C_ISR_ARLO I2C_ISR_ARLO_Msk /*!< Arbitration lost */ #define I2C_ISR_OVR_Pos (10U) #define I2C_ISR_OVR_Msk (0x1UL << I2C_ISR_OVR_Pos) /*!< 0x00000400 */ #define I2C_ISR_OVR I2C_ISR_OVR_Msk /*!< Overrun/Underrun */ #define I2C_ISR_PECERR_Pos (11U) #define I2C_ISR_PECERR_Msk (0x1UL << I2C_ISR_PECERR_Pos) /*!< 0x00000800 */ #define I2C_ISR_PECERR I2C_ISR_PECERR_Msk /*!< PEC error in reception */ #define I2C_ISR_TIMEOUT_Pos (12U) #define I2C_ISR_TIMEOUT_Msk (0x1UL << I2C_ISR_TIMEOUT_Pos) /*!< 0x00001000 */ #define I2C_ISR_TIMEOUT I2C_ISR_TIMEOUT_Msk /*!< Timeout or Tlow detection flag */ #define I2C_ISR_ALERT_Pos (13U) #define I2C_ISR_ALERT_Msk (0x1UL << I2C_ISR_ALERT_Pos) /*!< 0x00002000 */ #define I2C_ISR_ALERT I2C_ISR_ALERT_Msk /*!< SMBus alert */ #define I2C_ISR_BUSY_Pos (15U) #define I2C_ISR_BUSY_Msk (0x1UL << I2C_ISR_BUSY_Pos) /*!< 0x00008000 */ #define I2C_ISR_BUSY I2C_ISR_BUSY_Msk /*!< Bus busy */ #define I2C_ISR_DIR_Pos (16U) #define I2C_ISR_DIR_Msk (0x1UL << I2C_ISR_DIR_Pos) /*!< 0x00010000 */ #define I2C_ISR_DIR I2C_ISR_DIR_Msk /*!< Transfer direction (slave mode) */ #define I2C_ISR_ADDCODE_Pos (17U) #define I2C_ISR_ADDCODE_Msk (0x7FUL << I2C_ISR_ADDCODE_Pos) /*!< 0x00FE0000 */ #define I2C_ISR_ADDCODE I2C_ISR_ADDCODE_Msk /*!< Address match code (slave mode) */ /****************** Bit definition for I2C_ICR register *********************/ #define I2C_ICR_ADDRCF_Pos (3U) #define I2C_ICR_ADDRCF_Msk (0x1UL << I2C_ICR_ADDRCF_Pos) /*!< 0x00000008 */ #define I2C_ICR_ADDRCF I2C_ICR_ADDRCF_Msk /*!< Address matched clear flag */ #define I2C_ICR_NACKCF_Pos (4U) #define I2C_ICR_NACKCF_Msk (0x1UL << I2C_ICR_NACKCF_Pos) /*!< 0x00000010 */ #define I2C_ICR_NACKCF I2C_ICR_NACKCF_Msk /*!< NACK clear flag */ #define I2C_ICR_STOPCF_Pos (5U) #define I2C_ICR_STOPCF_Msk (0x1UL << I2C_ICR_STOPCF_Pos) /*!< 0x00000020 */ #define I2C_ICR_STOPCF I2C_ICR_STOPCF_Msk /*!< STOP detection clear flag */ #define I2C_ICR_BERRCF_Pos (8U) #define I2C_ICR_BERRCF_Msk (0x1UL << I2C_ICR_BERRCF_Pos) /*!< 0x00000100 */ #define I2C_ICR_BERRCF I2C_ICR_BERRCF_Msk /*!< Bus error clear flag */ #define I2C_ICR_ARLOCF_Pos (9U) #define I2C_ICR_ARLOCF_Msk (0x1UL << I2C_ICR_ARLOCF_Pos) /*!< 0x00000200 */ #define I2C_ICR_ARLOCF I2C_ICR_ARLOCF_Msk /*!< Arbitration lost clear flag */ #define I2C_ICR_OVRCF_Pos (10U) #define I2C_ICR_OVRCF_Msk (0x1UL << I2C_ICR_OVRCF_Pos) /*!< 0x00000400 */ #define I2C_ICR_OVRCF I2C_ICR_OVRCF_Msk /*!< Overrun/Underrun clear flag */ #define I2C_ICR_PECCF_Pos (11U) #define I2C_ICR_PECCF_Msk (0x1UL << I2C_ICR_PECCF_Pos) /*!< 0x00000800 */ #define I2C_ICR_PECCF I2C_ICR_PECCF_Msk /*!< PAC error clear flag */ #define I2C_ICR_TIMOUTCF_Pos (12U) #define I2C_ICR_TIMOUTCF_Msk (0x1UL << I2C_ICR_TIMOUTCF_Pos) /*!< 0x00001000 */ #define I2C_ICR_TIMOUTCF I2C_ICR_TIMOUTCF_Msk /*!< Timeout clear flag */ #define I2C_ICR_ALERTCF_Pos (13U) #define I2C_ICR_ALERTCF_Msk (0x1UL << I2C_ICR_ALERTCF_Pos) /*!< 0x00002000 */ #define I2C_ICR_ALERTCF I2C_ICR_ALERTCF_Msk /*!< Alert clear flag */ /****************** Bit definition for I2C_PECR register *********************/ #define I2C_PECR_PEC_Pos (0U) #define I2C_PECR_PEC_Msk (0xFFUL << I2C_PECR_PEC_Pos) /*!< 0x000000FF */ #define I2C_PECR_PEC I2C_PECR_PEC_Msk /*!< PEC register */ /****************** Bit definition for I2C_RXDR register *********************/ #define I2C_RXDR_RXDATA_Pos (0U) #define I2C_RXDR_RXDATA_Msk (0xFFUL << I2C_RXDR_RXDATA_Pos) /*!< 0x000000FF */ #define I2C_RXDR_RXDATA I2C_RXDR_RXDATA_Msk /*!< 8-bit receive data */ /****************** Bit definition for I2C_TXDR register *********************/ #define I2C_TXDR_TXDATA_Pos (0U) #define I2C_TXDR_TXDATA_Msk (0xFFUL << I2C_TXDR_TXDATA_Pos) /*!< 0x000000FF */ #define I2C_TXDR_TXDATA I2C_TXDR_TXDATA_Msk /*!< 8-bit transmit data */ /******************************************************************************/ /* */ /* Independent WATCHDOG (IWDG) */ /* */ /******************************************************************************/ /******************* Bit definition for IWDG_KR register ********************/ #define IWDG_KR_KEY_Pos (0U) #define IWDG_KR_KEY_Msk (0xFFFFUL << IWDG_KR_KEY_Pos) /*!< 0x0000FFFF */ #define IWDG_KR_KEY IWDG_KR_KEY_Msk /*! */ #define RTC_CR_ALRAIE_Pos (12U) #define RTC_CR_ALRAIE_Msk (0x1UL << RTC_CR_ALRAIE_Pos) /*!< 0x00001000 */ #define RTC_CR_ALRAIE RTC_CR_ALRAIE_Msk #define RTC_CR_TSE_Pos (11U) #define RTC_CR_TSE_Msk (0x1UL << RTC_CR_TSE_Pos) /*!< 0x00000800 */ #define RTC_CR_TSE RTC_CR_TSE_Msk /*!< timestamp enable > */ #define RTC_CR_ALRAE_Pos (8U) #define RTC_CR_ALRAE_Msk (0x1UL << RTC_CR_ALRAE_Pos) /*!< 0x00000100 */ #define RTC_CR_ALRAE RTC_CR_ALRAE_Msk #define RTC_CR_FMT_Pos (6U) #define RTC_CR_FMT_Msk (0x1UL << RTC_CR_FMT_Pos) /*!< 0x00000040 */ #define RTC_CR_FMT RTC_CR_FMT_Msk #define RTC_CR_BYPSHAD_Pos (5U) #define RTC_CR_BYPSHAD_Msk (0x1UL << RTC_CR_BYPSHAD_Pos) /*!< 0x00000020 */ #define RTC_CR_BYPSHAD RTC_CR_BYPSHAD_Msk #define RTC_CR_REFCKON_Pos (4U) #define RTC_CR_REFCKON_Msk (0x1UL << RTC_CR_REFCKON_Pos) /*!< 0x00000010 */ #define RTC_CR_REFCKON RTC_CR_REFCKON_Msk #define RTC_CR_TSEDGE_Pos (3U) #define RTC_CR_TSEDGE_Msk (0x1UL << RTC_CR_TSEDGE_Pos) /*!< 0x00000008 */ #define RTC_CR_TSEDGE RTC_CR_TSEDGE_Msk /*!< Timestamp event active edge > */ /******************** Bits definition for RTC_WPR register ******************/ #define RTC_WPR_KEY_Pos (0U) #define RTC_WPR_KEY_Msk (0xFFUL << RTC_WPR_KEY_Pos) /*!< 0x000000FF */ #define RTC_WPR_KEY RTC_WPR_KEY_Msk /******************** Bits definition for RTC_CALR register *****************/ #define RTC_CALR_CALP_Pos (15U) #define RTC_CALR_CALP_Msk (0x1UL << RTC_CALR_CALP_Pos) /*!< 0x00008000 */ #define RTC_CALR_CALP RTC_CALR_CALP_Msk #define RTC_CALR_CALW8_Pos (14U) #define RTC_CALR_CALW8_Msk (0x1UL << RTC_CALR_CALW8_Pos) /*!< 0x00004000 */ #define RTC_CALR_CALW8 RTC_CALR_CALW8_Msk #define RTC_CALR_CALW16_Pos (13U) #define RTC_CALR_CALW16_Msk (0x1UL << RTC_CALR_CALW16_Pos) /*!< 0x00002000 */ #define RTC_CALR_CALW16 RTC_CALR_CALW16_Msk #define RTC_CALR_CALM_Pos (0U) #define RTC_CALR_CALM_Msk (0x1FFUL << RTC_CALR_CALM_Pos) /*!< 0x000001FF */ #define RTC_CALR_CALM RTC_CALR_CALM_Msk #define RTC_CALR_CALM_0 (0x001UL << RTC_CALR_CALM_Pos) /*!< 0x00000001 */ #define RTC_CALR_CALM_1 (0x002UL << RTC_CALR_CALM_Pos) /*!< 0x00000002 */ #define RTC_CALR_CALM_2 (0x004UL << RTC_CALR_CALM_Pos) /*!< 0x00000004 */ #define RTC_CALR_CALM_3 (0x008UL << RTC_CALR_CALM_Pos) /*!< 0x00000008 */ #define RTC_CALR_CALM_4 (0x010UL << RTC_CALR_CALM_Pos) /*!< 0x00000010 */ #define RTC_CALR_CALM_5 (0x020UL << RTC_CALR_CALM_Pos) /*!< 0x00000020 */ #define RTC_CALR_CALM_6 (0x040UL << RTC_CALR_CALM_Pos) /*!< 0x00000040 */ #define RTC_CALR_CALM_7 (0x080UL << RTC_CALR_CALM_Pos) /*!< 0x00000080 */ #define RTC_CALR_CALM_8 (0x100UL << RTC_CALR_CALM_Pos) /*!< 0x00000100 */ /******************** Bits definition for RTC_SHIFTR register ***************/ #define RTC_SHIFTR_ADD1S_Pos (31U) #define RTC_SHIFTR_ADD1S_Msk (0x1UL << RTC_SHIFTR_ADD1S_Pos) /*!< 0x80000000 */ #define RTC_SHIFTR_ADD1S RTC_SHIFTR_ADD1S_Msk #define RTC_SHIFTR_SUBFS_Pos (0U) #define RTC_SHIFTR_SUBFS_Msk (0x7FFFUL << RTC_SHIFTR_SUBFS_Pos) /*!< 0x00007FFF */ #define RTC_SHIFTR_SUBFS RTC_SHIFTR_SUBFS_Msk /******************** Bits definition for RTC_TSTR register *****************/ #define RTC_TSTR_PM_Pos (22U) #define RTC_TSTR_PM_Msk (0x1UL << RTC_TSTR_PM_Pos) /*!< 0x00400000 */ #define RTC_TSTR_PM RTC_TSTR_PM_Msk /*!< AM-PM notation > */ #define RTC_TSTR_HT_Pos (20U) #define RTC_TSTR_HT_Msk (0x3UL << RTC_TSTR_HT_Pos) /*!< 0x00300000 */ #define RTC_TSTR_HT RTC_TSTR_HT_Msk #define RTC_TSTR_HT_0 (0x1UL << RTC_TSTR_HT_Pos) /*!< 0x00100000 */ #define RTC_TSTR_HT_1 (0x2UL << RTC_TSTR_HT_Pos) /*!< 0x00200000 */ #define RTC_TSTR_HU_Pos (16U) #define RTC_TSTR_HU_Msk (0xFUL << RTC_TSTR_HU_Pos) /*!< 0x000F0000 */ #define RTC_TSTR_HU RTC_TSTR_HU_Msk #define RTC_TSTR_HU_0 (0x1UL << RTC_TSTR_HU_Pos) /*!< 0x00010000 */ #define RTC_TSTR_HU_1 (0x2UL << RTC_TSTR_HU_Pos) /*!< 0x00020000 */ #define RTC_TSTR_HU_2 (0x4UL << RTC_TSTR_HU_Pos) /*!< 0x00040000 */ #define RTC_TSTR_HU_3 (0x8UL << RTC_TSTR_HU_Pos) /*!< 0x00080000 */ #define RTC_TSTR_MNT_Pos (12U) #define RTC_TSTR_MNT_Msk (0x7UL << RTC_TSTR_MNT_Pos) /*!< 0x00007000 */ #define RTC_TSTR_MNT RTC_TSTR_MNT_Msk #define RTC_TSTR_MNT_0 (0x1UL << RTC_TSTR_MNT_Pos) /*!< 0x00001000 */ #define RTC_TSTR_MNT_1 (0x2UL << RTC_TSTR_MNT_Pos) /*!< 0x00002000 */ #define RTC_TSTR_MNT_2 (0x4UL << RTC_TSTR_MNT_Pos) /*!< 0x00004000 */ #define RTC_TSTR_MNU_Pos (8U) #define RTC_TSTR_MNU_Msk (0xFUL << RTC_TSTR_MNU_Pos) /*!< 0x00000F00 */ #define RTC_TSTR_MNU RTC_TSTR_MNU_Msk #define RTC_TSTR_MNU_0 (0x1UL << RTC_TSTR_MNU_Pos) /*!< 0x00000100 */ #define RTC_TSTR_MNU_1 (0x2UL << RTC_TSTR_MNU_Pos) /*!< 0x00000200 */ #define RTC_TSTR_MNU_2 (0x4UL << RTC_TSTR_MNU_Pos) /*!< 0x00000400 */ #define RTC_TSTR_MNU_3 (0x8UL << RTC_TSTR_MNU_Pos) /*!< 0x00000800 */ #define RTC_TSTR_ST_Pos (4U) #define RTC_TSTR_ST_Msk (0x7UL << RTC_TSTR_ST_Pos) /*!< 0x00000070 */ #define RTC_TSTR_ST RTC_TSTR_ST_Msk #define RTC_TSTR_ST_0 (0x1UL << RTC_TSTR_ST_Pos) /*!< 0x00000010 */ #define RTC_TSTR_ST_1 (0x2UL << RTC_TSTR_ST_Pos) /*!< 0x00000020 */ #define RTC_TSTR_ST_2 (0x4UL << RTC_TSTR_ST_Pos) /*!< 0x00000040 */ #define RTC_TSTR_SU_Pos (0U) #define RTC_TSTR_SU_Msk (0xFUL << RTC_TSTR_SU_Pos) /*!< 0x0000000F */ #define RTC_TSTR_SU RTC_TSTR_SU_Msk #define RTC_TSTR_SU_0 (0x1UL << RTC_TSTR_SU_Pos) /*!< 0x00000001 */ #define RTC_TSTR_SU_1 (0x2UL << RTC_TSTR_SU_Pos) /*!< 0x00000002 */ #define RTC_TSTR_SU_2 (0x4UL << RTC_TSTR_SU_Pos) /*!< 0x00000004 */ #define RTC_TSTR_SU_3 (0x8UL << RTC_TSTR_SU_Pos) /*!< 0x00000008 */ /******************** Bits definition for RTC_TSDR register *****************/ #define RTC_TSDR_WDU_Pos (13U) #define RTC_TSDR_WDU_Msk (0x7UL << RTC_TSDR_WDU_Pos) /*!< 0x0000E000 */ #define RTC_TSDR_WDU RTC_TSDR_WDU_Msk /*!< Week day units > */ #define RTC_TSDR_WDU_0 (0x1UL << RTC_TSDR_WDU_Pos) /*!< 0x00002000 */ #define RTC_TSDR_WDU_1 (0x2UL << RTC_TSDR_WDU_Pos) /*!< 0x00004000 */ #define RTC_TSDR_WDU_2 (0x4UL << RTC_TSDR_WDU_Pos) /*!< 0x00008000 */ #define RTC_TSDR_MT_Pos (12U) #define RTC_TSDR_MT_Msk (0x1UL << RTC_TSDR_MT_Pos) /*!< 0x00001000 */ #define RTC_TSDR_MT RTC_TSDR_MT_Msk #define RTC_TSDR_MU_Pos (8U) #define RTC_TSDR_MU_Msk (0xFUL << RTC_TSDR_MU_Pos) /*!< 0x00000F00 */ #define RTC_TSDR_MU RTC_TSDR_MU_Msk #define RTC_TSDR_MU_0 (0x1UL << RTC_TSDR_MU_Pos) /*!< 0x00000100 */ #define RTC_TSDR_MU_1 (0x2UL << RTC_TSDR_MU_Pos) /*!< 0x00000200 */ #define RTC_TSDR_MU_2 (0x4UL << RTC_TSDR_MU_Pos) /*!< 0x00000400 */ #define RTC_TSDR_MU_3 (0x8UL << RTC_TSDR_MU_Pos) /*!< 0x00000800 */ #define RTC_TSDR_DT_Pos (4U) #define RTC_TSDR_DT_Msk (0x3UL << RTC_TSDR_DT_Pos) /*!< 0x00000030 */ #define RTC_TSDR_DT RTC_TSDR_DT_Msk #define RTC_TSDR_DT_0 (0x1UL << RTC_TSDR_DT_Pos) /*!< 0x00000010 */ #define RTC_TSDR_DT_1 (0x2UL << RTC_TSDR_DT_Pos) /*!< 0x00000020 */ #define RTC_TSDR_DU_Pos (0U) #define RTC_TSDR_DU_Msk (0xFUL << RTC_TSDR_DU_Pos) /*!< 0x0000000F */ #define RTC_TSDR_DU RTC_TSDR_DU_Msk #define RTC_TSDR_DU_0 (0x1UL << RTC_TSDR_DU_Pos) /*!< 0x00000001 */ #define RTC_TSDR_DU_1 (0x2UL << RTC_TSDR_DU_Pos) /*!< 0x00000002 */ #define RTC_TSDR_DU_2 (0x4UL << RTC_TSDR_DU_Pos) /*!< 0x00000004 */ #define RTC_TSDR_DU_3 (0x8UL << RTC_TSDR_DU_Pos) /*!< 0x00000008 */ /******************** Bits definition for RTC_TSSSR register ****************/ #define RTC_TSSSR_SS_Pos (0U) #define RTC_TSSSR_SS_Msk (0xFFFFUL << RTC_TSSSR_SS_Pos) /*!< 0x0000FFFF */ #define RTC_TSSSR_SS RTC_TSSSR_SS_Msk /*!< Sub second value > */ /******************** Bits definition for RTC_ALRMAR register ***************/ #define RTC_ALRMAR_MSK4_Pos (31U) #define RTC_ALRMAR_MSK4_Msk (0x1UL << RTC_ALRMAR_MSK4_Pos) /*!< 0x80000000 */ #define RTC_ALRMAR_MSK4 RTC_ALRMAR_MSK4_Msk #define RTC_ALRMAR_WDSEL_Pos (30U) #define RTC_ALRMAR_WDSEL_Msk (0x1UL << RTC_ALRMAR_WDSEL_Pos) /*!< 0x40000000 */ #define RTC_ALRMAR_WDSEL RTC_ALRMAR_WDSEL_Msk #define RTC_ALRMAR_DT_Pos (28U) #define RTC_ALRMAR_DT_Msk (0x3UL << RTC_ALRMAR_DT_Pos) /*!< 0x30000000 */ #define RTC_ALRMAR_DT RTC_ALRMAR_DT_Msk #define RTC_ALRMAR_DT_0 (0x1UL << RTC_ALRMAR_DT_Pos) /*!< 0x10000000 */ #define RTC_ALRMAR_DT_1 (0x2UL << RTC_ALRMAR_DT_Pos) /*!< 0x20000000 */ #define RTC_ALRMAR_DU_Pos (24U) #define RTC_ALRMAR_DU_Msk (0xFUL << RTC_ALRMAR_DU_Pos) /*!< 0x0F000000 */ #define RTC_ALRMAR_DU RTC_ALRMAR_DU_Msk #define RTC_ALRMAR_DU_0 (0x1UL << RTC_ALRMAR_DU_Pos) /*!< 0x01000000 */ #define RTC_ALRMAR_DU_1 (0x2UL << RTC_ALRMAR_DU_Pos) /*!< 0x02000000 */ #define RTC_ALRMAR_DU_2 (0x4UL << RTC_ALRMAR_DU_Pos) /*!< 0x04000000 */ #define RTC_ALRMAR_DU_3 (0x8UL << RTC_ALRMAR_DU_Pos) /*!< 0x08000000 */ #define RTC_ALRMAR_MSK3_Pos (23U) #define RTC_ALRMAR_MSK3_Msk (0x1UL << RTC_ALRMAR_MSK3_Pos) /*!< 0x00800000 */ #define RTC_ALRMAR_MSK3 RTC_ALRMAR_MSK3_Msk #define RTC_ALRMAR_PM_Pos (22U) #define RTC_ALRMAR_PM_Msk (0x1UL << RTC_ALRMAR_PM_Pos) /*!< 0x00400000 */ #define RTC_ALRMAR_PM RTC_ALRMAR_PM_Msk #define RTC_ALRMAR_HT_Pos (20U) #define RTC_ALRMAR_HT_Msk (0x3UL << RTC_ALRMAR_HT_Pos) /*!< 0x00300000 */ #define RTC_ALRMAR_HT RTC_ALRMAR_HT_Msk #define RTC_ALRMAR_HT_0 (0x1UL << RTC_ALRMAR_HT_Pos) /*!< 0x00100000 */ #define RTC_ALRMAR_HT_1 (0x2UL << RTC_ALRMAR_HT_Pos) /*!< 0x00200000 */ #define RTC_ALRMAR_HU_Pos (16U) #define RTC_ALRMAR_HU_Msk (0xFUL << RTC_ALRMAR_HU_Pos) /*!< 0x000F0000 */ #define RTC_ALRMAR_HU RTC_ALRMAR_HU_Msk #define RTC_ALRMAR_HU_0 (0x1UL << RTC_ALRMAR_HU_Pos) /*!< 0x00010000 */ #define RTC_ALRMAR_HU_1 (0x2UL << RTC_ALRMAR_HU_Pos) /*!< 0x00020000 */ #define RTC_ALRMAR_HU_2 (0x4UL << RTC_ALRMAR_HU_Pos) /*!< 0x00040000 */ #define RTC_ALRMAR_HU_3 (0x8UL << RTC_ALRMAR_HU_Pos) /*!< 0x00080000 */ #define RTC_ALRMAR_MSK2_Pos (15U) #define RTC_ALRMAR_MSK2_Msk (0x1UL << RTC_ALRMAR_MSK2_Pos) /*!< 0x00008000 */ #define RTC_ALRMAR_MSK2 RTC_ALRMAR_MSK2_Msk #define RTC_ALRMAR_MNT_Pos (12U) #define RTC_ALRMAR_MNT_Msk (0x7UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00007000 */ #define RTC_ALRMAR_MNT RTC_ALRMAR_MNT_Msk #define RTC_ALRMAR_MNT_0 (0x1UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00001000 */ #define RTC_ALRMAR_MNT_1 (0x2UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00002000 */ #define RTC_ALRMAR_MNT_2 (0x4UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00004000 */ #define RTC_ALRMAR_MNU_Pos (8U) #define RTC_ALRMAR_MNU_Msk (0xFUL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000F00 */ #define RTC_ALRMAR_MNU RTC_ALRMAR_MNU_Msk #define RTC_ALRMAR_MNU_0 (0x1UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000100 */ #define RTC_ALRMAR_MNU_1 (0x2UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000200 */ #define RTC_ALRMAR_MNU_2 (0x4UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000400 */ #define RTC_ALRMAR_MNU_3 (0x8UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000800 */ #define RTC_ALRMAR_MSK1_Pos (7U) #define RTC_ALRMAR_MSK1_Msk (0x1UL << RTC_ALRMAR_MSK1_Pos) /*!< 0x00000080 */ #define RTC_ALRMAR_MSK1 RTC_ALRMAR_MSK1_Msk #define RTC_ALRMAR_ST_Pos (4U) #define RTC_ALRMAR_ST_Msk (0x7UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000070 */ #define RTC_ALRMAR_ST RTC_ALRMAR_ST_Msk #define RTC_ALRMAR_ST_0 (0x1UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000010 */ #define RTC_ALRMAR_ST_1 (0x2UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000020 */ #define RTC_ALRMAR_ST_2 (0x4UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000040 */ #define RTC_ALRMAR_SU_Pos (0U) #define RTC_ALRMAR_SU_Msk (0xFUL << RTC_ALRMAR_SU_Pos) /*!< 0x0000000F */ #define RTC_ALRMAR_SU RTC_ALRMAR_SU_Msk #define RTC_ALRMAR_SU_0 (0x1UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000001 */ #define RTC_ALRMAR_SU_1 (0x2UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000002 */ #define RTC_ALRMAR_SU_2 (0x4UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000004 */ #define RTC_ALRMAR_SU_3 (0x8UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000008 */ /******************** Bits definition for RTC_ALRMASSR register *************/ #define RTC_ALRMASSR_MASKSS_Pos (24U) #define RTC_ALRMASSR_MASKSS_Msk (0xFUL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x0F000000 */ #define RTC_ALRMASSR_MASKSS RTC_ALRMASSR_MASKSS_Msk #define RTC_ALRMASSR_MASKSS_0 (0x1UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x01000000 */ #define RTC_ALRMASSR_MASKSS_1 (0x2UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x02000000 */ #define RTC_ALRMASSR_MASKSS_2 (0x4UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x04000000 */ #define RTC_ALRMASSR_MASKSS_3 (0x8UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x08000000 */ #define RTC_ALRMASSR_SS_Pos (0U) #define RTC_ALRMASSR_SS_Msk (0x7FFFUL << RTC_ALRMASSR_SS_Pos) /*!< 0x00007FFF */ #define RTC_ALRMASSR_SS RTC_ALRMASSR_SS_Msk /******************** Bits definition for RTC_SR register *******************/ #define RTC_SR_TSOVF_Pos (4U) #define RTC_SR_TSOVF_Msk (0x1UL << RTC_SR_TSOVF_Pos) /*!< 0x00000010 */ #define RTC_SR_TSOVF RTC_SR_TSOVF_Msk /*!< Timestamp overflow flag > */ #define RTC_SR_TSF_Pos (3U) #define RTC_SR_TSF_Msk (0x1UL << RTC_SR_TSF_Pos) /*!< 0x00000008 */ #define RTC_SR_TSF RTC_SR_TSF_Msk /*!< Timestamp flag > */ #define RTC_SR_ALRAF_Pos (0U) #define RTC_SR_ALRAF_Msk (0x1UL << RTC_SR_ALRAF_Pos) /*!< 0x00000001 */ #define RTC_SR_ALRAF RTC_SR_ALRAF_Msk /******************** Bits definition for RTC_MISR register *****************/ #define RTC_MISR_TSOVMF_Pos (4U) #define RTC_MISR_TSOVMF_Msk (0x1UL << RTC_MISR_TSOVMF_Pos) /*!< 0x00000010 */ #define RTC_MISR_TSOVMF RTC_MISR_TSOVMF_Msk /*!< Timestamp overflow masked flag > */ #define RTC_MISR_TSMF_Pos (3U) #define RTC_MISR_TSMF_Msk (0x1UL << RTC_MISR_TSMF_Pos) /*!< 0x00000008 */ #define RTC_MISR_TSMF RTC_MISR_TSMF_Msk /*!< Timestamp masked flag > */ #define RTC_MISR_ALRAMF_Pos (0U) #define RTC_MISR_ALRAMF_Msk (0x1UL << RTC_MISR_ALRAMF_Pos) /*!< 0x00000001 */ #define RTC_MISR_ALRAMF RTC_MISR_ALRAMF_Msk /******************** Bits definition for RTC_SCR register ******************/ #define RTC_SCR_CTSOVF_Pos (4U) #define RTC_SCR_CTSOVF_Msk (0x1UL << RTC_SCR_CTSOVF_Pos) /*!< 0x00000010 */ #define RTC_SCR_CTSOVF RTC_SCR_CTSOVF_Msk /*!< Clear timestamp overflow flag > */ #define RTC_SCR_CTSF_Pos (3U) #define RTC_SCR_CTSF_Msk (0x1UL << RTC_SCR_CTSF_Pos) /*!< 0x00000008 */ #define RTC_SCR_CTSF RTC_SCR_CTSF_Msk /*!< Clear timestamp flag > */ #define RTC_SCR_CALRAF_Pos (0U) #define RTC_SCR_CALRAF_Msk (0x1UL << RTC_SCR_CALRAF_Pos) /*!< 0x00000001 */ #define RTC_SCR_CALRAF RTC_SCR_CALRAF_Msk /******************************************************************************/ /* */ /* Serial Peripheral Interface (SPI) */ /* */ /******************************************************************************/ #define SPI_I2S_SUPPORT /*!< I2S support */ /******************* Bit definition for SPI_CR1 register ********************/ #define SPI_CR1_CPHA_Pos (0U) #define SPI_CR1_CPHA_Msk (0x1UL << SPI_CR1_CPHA_Pos) /*!< 0x00000001 */ #define SPI_CR1_CPHA SPI_CR1_CPHA_Msk /*!VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ #else SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ #endif } /** * @brief Update SystemCoreClock variable according to Clock Register Values. * The SystemCoreClock variable contains the core clock (HCLK), it can * be used by the user application to setup the SysTick timer or configure * other parameters. * * @note Each time the core clock (HCLK) changes, this function must be called * to update SystemCoreClock variable value. Otherwise, any configuration * based on this variable will be incorrect. * * @note - The system frequency computed by this function is not the real * frequency in the chip. It is calculated based on the predefined * constant and the selected clock source: * * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) / HSI division factor * * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) * * - If SYSCLK source is LSI, SystemCoreClock will contain the LSI_VALUE * * - If SYSCLK source is LSE, SystemCoreClock will contain the LSE_VALUE * * (**) HSI_VALUE is a constant defined in stm32c0xx_hal_conf.h file (default value * 48 MHz) but the real value may vary depending on the variations * in voltage and temperature. * * (***) HSE_VALUE is a constant defined in stm32c0xx_hal_conf.h file (default value * 48 MHz), user has to ensure that HSE_VALUE is same as the real * frequency of the crystal used. Otherwise, this function may * have wrong result. * * - The result of this function could be not correct when using fractional * value for HSE crystal. * * @param None * @retval None */ void SystemCoreClockUpdate(void) { uint32_t tmp; uint32_t hsidiv; /* Get SYSCLK source -------------------------------------------------------*/ switch (RCC->CFGR & RCC_CFGR_SWS) { case RCC_CFGR_SWS_0: /* HSE used as system clock */ SystemCoreClock = HSE_VALUE; break; case (RCC_CFGR_SWS_1 | RCC_CFGR_SWS_0): /* LSI used as system clock */ SystemCoreClock = LSI_VALUE; break; case RCC_CFGR_SWS_2: /* LSE used as system clock */ SystemCoreClock = LSE_VALUE; break; case 0x00000000U: /* HSI used as system clock */ default: /* HSI used as system clock */ hsidiv = (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV))>> RCC_CR_HSIDIV_Pos)); SystemCoreClock = (HSI_VALUE/hsidiv); break; } /* Compute HCLK clock frequency --------------------------------------------*/ /* Get HCLK prescaler */ tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)]; /* HCLK clock frequency */ SystemCoreClock >>= tmp; } /** * @} */ /** * @} */ /** * @} */ ================================================ FILE: 3rd_party/nucleo-c031c6/system_stm32c0xx.h ================================================ /** ****************************************************************************** * @file system_stm32c0xx.h * @author MCD Application Team * @brief CMSIS Cortex-M0+ Device System Source File for STM32C0xx devices. ****************************************************************************** * @attention * * Copyright (c) 2022 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /** @addtogroup CMSIS * @{ */ /** @addtogroup stm32c0xx_system * @{ */ /** * @brief Define to prevent recursive inclusion */ #ifndef SYSTEM_STM32C0XX_H #define SYSTEM_STM32C0XX_H #ifdef __cplusplus extern "C" { #endif /** @addtogroup STM32C0xx_System_Includes * @{ */ /** * @} */ /** @addtogroup STM32C0xx_System_Exported_types * @{ */ /* This variable is updated in three ways: 1) by calling CMSIS function SystemCoreClockUpdate() 2) by calling HAL API function HAL_RCC_GetSysClockFreq() 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency Note: If you use this function to configure the system clock; then there is no need to call the 2 first functions listed above, since SystemCoreClock variable is updated automatically. */ extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ extern const uint32_t AHBPrescTable[16]; /*!< AHB prescalers table values */ extern const uint32_t APBPrescTable[8]; /*!< APB prescalers table values */ /** * @} */ /** @addtogroup STM32C0xx_System_Exported_Constants * @{ */ /** * @} */ /** @addtogroup STM32C0xx_System_Exported_Macros * @{ */ /** * @} */ /** @addtogroup STM32C0xx_System_Exported_Functions * @{ */ extern void SystemInit(void); extern void SystemCoreClockUpdate(void); /** * @} */ #ifdef __cplusplus } #endif #endif /*SYSTEM_STM32C0XX_H */ /** * @} */ /** * @} */ ================================================ FILE: 3rd_party/nucleo-h743zi/README.txt ================================================ This folder contains the support code for the NUCLEO-H743ZI board. CMSIS-Compliant Device Files ============================ The code also includes the CMSIS-compliant interface to the STM32L053xx MCU files: arm\startup_stm32h743xx.s gnu\startup_stm32h743xx.c iar\startup_stm32h743xx.s cmsis_* stm32h7xx.h stm32h743xx.h system_stm32h7xx.h system_stm32h7xx.c ================================================ FILE: 3rd_party/nucleo-h743zi/arm/startup_stm32h743xx.s ================================================ ;/***************************************************************************/ ; * @file startup_stm32h743xx.s for ARM-KEIL ARM assembler ; * @brief CMSIS Cortex-M7 Core Device Startup File for STM32H743xx ; * @version CMSIS 5.9.0 ; * @date 1 Feb 2023 ; * ; * Modified by Quantum Leaps: ; * - Added relocating of the Vector Table to free up the 256B region at 0x0 ; * for NULL-pointer protection by the MPU. ; * - Modified all exception handlers to branch to assert_failed() ; * instead of locking up the CPU inside an endless loop. ; * ; * @description ; * Created from the CMSIS template for the specified device ; * Quantum Leaps, www.state-machine.com ; * ; * @note ; * The symbols Stack_Size and Heap_Size should be provided on the command- ; * line options to the assembler, for example as: ; * --pd "Stack_Size SETA 1024" --pd "Heap_Size SETA 0" ;****************************************************************************** ; Allocate space for the stack. ; AREA STACK, NOINIT, READWRITE, ALIGN=3 __stack_base StackMem SPACE Stack_Size ; provided in command-line option, for example: ; --pd "Stack_Size SETA 512" __stack_limit __initial_sp ;****************************************************************************** ; Allocate space for the heap. ; AREA HEAP, NOINIT, READWRITE, ALIGN=3 __heap_base HeapMem SPACE Heap_Size ; provided in command-line option, for example: ; --pd "Heap_Size SETA 0" __heap_limit ; Indicate that the code in this file preserves 8-byte alignment of the stack. PRESERVE8 ;****************************************************************************** ; The vector table. ; ; Place code into the reset code section. AREA RESET, DATA, READONLY, ALIGN=8 EXPORT __Vectors EXPORT __Vectors_End EXPORT __Vectors_Size __Vectors ; Initial Vector Table before relocation DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD SVC_Handler ; SVCall handler DCD DebugMon_Handler ; Debug Monitor handler DCD Default_Handler ; Reserved DCD PendSV_Handler ; PendSV handler DCD SysTick_Handler ; SysTick handler ; IRQ handlers... DCD WWDG_IRQHandler ; [ 0] Window WatchDog Interrupt ( wwdg1_it) DCD PVD_AVD_IRQHandler ; [ 1] PVD/AVD through EXTI Line detection DCD TAMP_STAMP_IRQHandler ; [ 2] Tamper and TimeStamps through EXTI line DCD RTC_WKUP_IRQHandler ; [ 3] RTC Wakeup through the EXTI line DCD FLASH_IRQHandler ; [ 4] FLASH DCD RCC_IRQHandler ; [ 5] RCC DCD EXTI0_IRQHandler ; [ 6] EXTI Line0 DCD EXTI1_IRQHandler ; [ 7] EXTI Line1 DCD EXTI2_IRQHandler ; [ 8] EXTI Line2 DCD EXTI3_IRQHandler ; [ 9] EXTI Line3 DCD EXTI4_IRQHandler ; [10] EXTI Line4 DCD DMA1_Stream0_IRQHandler ; [11] DMA1 Stream 0 DCD DMA1_Stream1_IRQHandler ; [12] DMA1 Stream 1 DCD DMA1_Stream2_IRQHandler ; [13] DMA1 Stream 2 DCD DMA1_Stream3_IRQHandler ; [14] DMA1 Stream 3 DCD DMA1_Stream4_IRQHandler ; [15] DMA1 Stream 4 DCD DMA1_Stream5_IRQHandler ; [16] DMA1 Stream 5 DCD DMA1_Stream6_IRQHandler ; [17] DMA1 Stream 6 DCD ADC_IRQHandler ; [18] ADC1, ADC2 DCD FDCAN1_IT0_IRQHandler ; [19] FDCAN1 interrupt line 0 DCD FDCAN2_IT0_IRQHandler ; [20] FDCAN2 interrupt line 0 DCD FDCAN1_IT1_IRQHandler ; [21] FDCAN1 interrupt line 1 DCD FDCAN2_IT1_IRQHandler ; [22] FDCAN2 interrupt line 1 DCD EXTI9_5_IRQHandler ; [23] External Line[9:5]s DCD TIM1_BRK_IRQHandler ; [24] TIM1 Break interrupt DCD TIM1_UP_IRQHandler ; [25] TIM1 Update DCD TIM1_TRG_COM_IRQHandler ; [26] TIM1 Trigger and Commutation Interrupt DCD TIM1_CC_IRQHandler ; [27] TIM1 Capture Compare DCD TIM2_IRQHandler ; [28] TIM2 DCD TIM3_IRQHandler ; [29] TIM3 DCD TIM4_IRQHandler ; [30] TIM4 DCD I2C1_EV_IRQHandler ; [31] I2C1 Event DCD I2C1_ER_IRQHandler ; [32] I2C1 Error DCD I2C2_EV_IRQHandler ; [33] I2C2 Event DCD I2C2_ER_IRQHandler ; [34] I2C2 Error DCD SPI1_IRQHandler ; [35] SPI1 DCD SPI2_IRQHandler ; [36] SPI2 DCD USART1_IRQHandler ; [37] USART1 DCD USART2_IRQHandler ; [38] USART2 DCD USART3_IRQHandler ; [39] USART3 DCD EXTI15_10_IRQHandler ; [40] External Line[15:10] DCD RTC_Alarm_IRQHandler ; [41] RTC Alarm (A and B) through EXTI Line DCD Reserved42_IRQHandler ; [42] Reserved DCD TIM8_BRK_TIM12_IRQHandler ; [43] TIM8 Break Interrupt and TIM12 global interrupt DCD TIM8_UP_TIM13_IRQHandler ; [44] TIM8 Update Interrupt and TIM13 global interrupt DCD TIM8_TRG_COM_TIM14_IRQHandler;[45] TIM8 Trigger and Commutation Interrupt and TIM14 glob DCD TIM8_CC_IRQHandler ; [46] TIM8 Capture Compare Interrupt DCD DMA1_Stream7_IRQHandler ; [47] DMA1 Stream7 DCD FMC_IRQHandler ; [48] FMC DCD SDMMC1_IRQHandler ; [49] SDMMC1 DCD TIM5_IRQHandler ; [50] TIM5 DCD SPI3_IRQHandler ; [51] SPI3 DCD UART4_IRQHandler ; [52] UART4 DCD UART5_IRQHandler ; [53] UART5 DCD TIM6_DAC_IRQHandler ; [54] TIM6 and DAC1&2 underrun errors DCD TIM7_IRQHandler ; [55] TIM7 DCD DMA2_Stream0_IRQHandler ; [56] DMA2 Stream 0 DCD DMA2_Stream1_IRQHandler ; [57] DMA2 Stream 1 DCD DMA2_Stream2_IRQHandler ; [58] DMA2 Stream 2 DCD DMA2_Stream3_IRQHandler ; [59] DMA2 Stream 3 DCD DMA2_Stream4_IRQHandler ; [60] DMA2 Stream 4 DCD ETH_IRQHandler ; [61] Ethernet DCD ETH_WKUP_IRQHandler ; [62] Ethernet Wakeup through EXTI line DCD FDCAN_CAL_IRQHandler ; [63] FDCAN calibration unit interrupt DCD Reserved64_IRQHandler ; [64] Reserved DCD Reserved65_IRQHandler ; [65] Reserved DCD Reserved66_IRQHandler ; [66] Reserved DCD Reserved67_IRQHandler ; [67] Reserved DCD DMA2_Stream5_IRQHandler ; [68] DMA2 Stream 5 DCD DMA2_Stream6_IRQHandler ; [69] DMA2 Stream 6 DCD DMA2_Stream7_IRQHandler ; [70] DMA2 Stream 7 DCD USART6_IRQHandler ; [71] USART6 DCD I2C3_EV_IRQHandler ; [72] I2C3 event DCD I2C3_ER_IRQHandler ; [73] I2C3 error DCD OTG_HS_EP1_OUT_IRQHandler ; [74] USB OTG HS End Point 1 Out DCD OTG_HS_EP1_IN_IRQHandler ; [75] USB OTG HS End Point 1 In DCD OTG_HS_WKUP_IRQHandler ; [76] USB OTG HS Wakeup through EXTI DCD OTG_HS_IRQHandler ; [77] USB OTG HS DCD DCMI_IRQHandler ; [78] DCMI DCD Reserved79_IRQHandler ; [79] Reserved DCD RNG_IRQHandler ; [80] Rng DCD FPU_IRQHandler ; [81] FPU DCD UART7_IRQHandler ; [82] UART7 DCD UART8_IRQHandler ; [83] UART8 DCD SPI4_IRQHandler ; [84] SPI4 DCD SPI5_IRQHandler ; [85] SPI5 DCD SPI6_IRQHandler ; [86] SPI6 DCD SAI1_IRQHandler ; [87] SAI1 DCD LTDC_IRQHandler ; [88] LTDC DCD LTDC_ER_IRQHandler ; [89] LTDC error DCD DMA2D_IRQHandler ; [90] DMA2D DCD SAI2_IRQHandler ; [91] SAI2 DCD QUADSPI_IRQHandler ; [92] QUADSPI DCD LPTIM1_IRQHandler ; [93] LPTIM1 DCD CEC_IRQHandler ; [94] HDMI_CEC DCD I2C4_EV_IRQHandler ; [95] I2C4 Event DCD I2C4_ER_IRQHandler ; [96] I2C4 Error DCD SPDIF_RX_IRQHandler ; [97] SPDIF_RX DCD OTG_FS_EP1_OUT_IRQHandler ; [98] USB OTG FS End Point 1 Out DCD OTG_FS_EP1_IN_IRQHandler ; [99] USB OTG FS End Point 1 In DCD OTG_FS_WKUP_IRQHandler ; [100] USB OTG FS Wakeup through EXTI DCD OTG_FS_IRQHandler ; [101] USB OTG FS DCD DMAMUX1_OVR_IRQHandler ; [102] DMAMUX1 Overrun interrupt DCD HRTIM1_Master_IRQHandler ; [103] HRTIM Master Timer global Interrupts DCD HRTIM1_TIMA_IRQHandler ; [104] HRTIM Timer A global Interrupt DCD HRTIM1_TIMB_IRQHandler ; [105] HRTIM Timer B global Interrupt DCD HRTIM1_TIMC_IRQHandler ; [106] HRTIM Timer C global Interrupt DCD HRTIM1_TIMD_IRQHandler ; [107] HRTIM Timer D global Interrupt DCD HRTIM1_TIME_IRQHandler ; [108] HRTIM Timer E global Interrupt DCD HRTIM1_FLT_IRQHandler ; [109] HRTIM Fault global Interrupt DCD DFSDM1_FLT0_IRQHandler ; [110] DFSDM Filter0 Interrupt DCD DFSDM1_FLT1_IRQHandler ; [111] DFSDM Filter1 Interrupt DCD DFSDM1_FLT2_IRQHandler ; [112] DFSDM Filter2 Interrupt DCD DFSDM1_FLT3_IRQHandler ; [113] DFSDM Filter3 Interrupt DCD SAI3_IRQHandler ; [114] SAI3 global Interrupt DCD SWPMI1_IRQHandler ; [115] Serial Wire Interface 1 global interrupt DCD TIM15_IRQHandler ; [116] TIM15 global Interrupt DCD TIM16_IRQHandler ; [117] TIM16 global Interrupt DCD TIM17_IRQHandler ; [118] TIM17 global Interrupt DCD MDIOS_WKUP_IRQHandler ; [119] MDIOS Wakeup Interrupt DCD MDIOS_IRQHandler ; [120] MDIOS global Interrupt DCD JPEG_IRQHandler ; [121] JPEG global Interrupt DCD MDMA_IRQHandler ; [122] MDMA global Interrupt DCD Reserved123_IRQHandler ; [123] Reserved DCD SDMMC2_IRQHandler ; [124] SDMMC2 global Interrupt DCD HSEM1_IRQHandler ; [125] HSEM1 global Interrupt DCD Reserved126_IRQHandler ; [126] Reserved DCD ADC3_IRQHandler ; [127] ADC3 global Interrupt DCD DMAMUX2_OVR_IRQHandler ; [128] DMAMUX Overrun interrupt DCD BDMA_Channel0_IRQHandler ; [129] BDMA Channel 0 global Interrupt DCD BDMA_Channel1_IRQHandler ; [130] BDMA Channel 1 global Interrupt DCD BDMA_Channel2_IRQHandler ; [131] BDMA Channel 2 global Interrupt DCD BDMA_Channel3_IRQHandler ; [132] BDMA Channel 3 global Interrupt DCD BDMA_Channel4_IRQHandler ; [133] BDMA Channel 4 global Interrupt DCD BDMA_Channel5_IRQHandler ; [134] BDMA Channel 5 global Interrupt DCD BDMA_Channel6_IRQHandler ; [135] BDMA Channel 6 global Interrupt DCD BDMA_Channel7_IRQHandler ; [136] BDMA Channel 7 global Interrupt DCD COMP1_IRQHandler ; [137] COMP1 global Interrupt DCD LPTIM2_IRQHandler ; [138] LP TIM2 global interrupt DCD LPTIM3_IRQHandler ; [139] LP TIM3 global interrupt DCD LPTIM4_IRQHandler ; [140] LP TIM4 global interrupt DCD LPTIM5_IRQHandler ; [141] LP TIM5 global interrupt DCD LPUART1_IRQHandler ; [142] LP UART1 interrupt DCD Reserved143_IRQHandler ; [143] Reserved DCD CRS_IRQHandler ; [144] Clock Recovery Global Interrupt DCD Reserved145_IRQHandler ; [145] Reserved DCD SAI4_IRQHandler ; [146] SAI4 global interrupt DCD Reserved147_IRQHandler ; [147] Reserved DCD Reserved148_IRQHandler ; [148] Reserved DCD WAKEUP_PIN_IRQHandler ; [149] Interrupt for all 6 wake-up pins __Vectors_End __Vectors_Size EQU __Vectors_End - __Vectors ;****************************************************************************** ; This is the code for exception handlers. ; AREA |.text|, CODE, READONLY ;****************************************************************************** ; This is the code that gets called when the processor first starts execution ; following a reset event. ; Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main IMPORT assert_failed LDR r0,=SystemInit ; CMSIS system initialization BLX r0 ; Call the C library enty point that handles startup. This will copy ; the .data section initializers from flash to SRAM and zero fill the ; .bss section. ; NOTE: The __main function clears the C stack as well LDR r0,=__main BX r0 ; __main calls the main() function, which should not return, ; but just in case jump to assert_failed() if main returns. LDR r0,=str_EXIT MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_EXIT DCB "EXIT" ALIGN ENDP ;****************************************************************************** NMI_Handler PROC EXPORT NMI_Handler [WEAK] IMPORT assert_failed LDR r0,=str_NMI MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_NMI DCB "NMI" ALIGN ENDP ;****************************************************************************** HardFault_Handler PROC EXPORT HardFault_Handler [WEAK] IMPORT assert_failed LDR r0,=str_HardFault MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_HardFault DCB "HardFault" ALIGN ENDP ;****************************************************************************** MemManage_Handler PROC EXPORT MemManage_Handler [WEAK] IMPORT assert_failed LDR r0,=str_MemManage MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_MemManage DCB "MemManage" ALIGN ENDP ;****************************************************************************** BusFault_Handler PROC EXPORT BusFault_Handler [WEAK] IMPORT assert_failed LDR r0,=str_BusFault MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_BusFault DCB "BusFault" ALIGN ENDP ;****************************************************************************** UsageFault_Handler PROC EXPORT UsageFault_Handler [WEAK] IMPORT assert_failed LDR r0,=str_UsageFault MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_UsageFault DCB "UsageFault" ALIGN ENDP ;****************************************************************************** ; ; Weak non-fault handlers... ; ;****************************************************************************** SVC_Handler PROC EXPORT SVC_Handler [WEAK] IMPORT assert_failed LDR r0,=str_SVC MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_SVC DCB "SVC" ALIGN ENDP ;****************************************************************************** DebugMon_Handler PROC EXPORT DebugMon_Handler [WEAK] IMPORT assert_failed LDR r0,=str_DebugMon MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_DebugMon DCB "DebugMon" ALIGN ENDP ;****************************************************************************** PendSV_Handler PROC EXPORT PendSV_Handler [WEAK] IMPORT assert_failed LDR r0,=str_PendSV MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_PendSV DCB "PendSV" ALIGN ENDP ;****************************************************************************** SysTick_Handler PROC EXPORT SysTick_Handler [WEAK] IMPORT assert_failed LDR r0,=str_SysTick MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_SysTick DCB "SysTick" ALIGN ENDP ;****************************************************************************** Default_Handler PROC EXPORT WWDG_IRQHandler [WEAK] EXPORT PVD_AVD_IRQHandler [WEAK] EXPORT TAMP_STAMP_IRQHandler [WEAK] EXPORT RTC_WKUP_IRQHandler [WEAK] EXPORT FLASH_IRQHandler [WEAK] EXPORT RCC_IRQHandler [WEAK] EXPORT EXTI0_IRQHandler [WEAK] EXPORT EXTI1_IRQHandler [WEAK] EXPORT EXTI2_IRQHandler [WEAK] EXPORT EXTI3_IRQHandler [WEAK] EXPORT EXTI4_IRQHandler [WEAK] EXPORT DMA1_Stream0_IRQHandler [WEAK] EXPORT DMA1_Stream1_IRQHandler [WEAK] EXPORT DMA1_Stream2_IRQHandler [WEAK] EXPORT DMA1_Stream3_IRQHandler [WEAK] EXPORT DMA1_Stream4_IRQHandler [WEAK] EXPORT DMA1_Stream5_IRQHandler [WEAK] EXPORT DMA1_Stream6_IRQHandler [WEAK] EXPORT ADC_IRQHandler [WEAK] EXPORT FDCAN1_IT0_IRQHandler [WEAK] EXPORT FDCAN2_IT0_IRQHandler [WEAK] EXPORT FDCAN1_IT1_IRQHandler [WEAK] EXPORT FDCAN2_IT1_IRQHandler [WEAK] EXPORT EXTI9_5_IRQHandler [WEAK] EXPORT TIM1_BRK_IRQHandler [WEAK] EXPORT TIM1_UP_IRQHandler [WEAK] EXPORT TIM1_TRG_COM_IRQHandler [WEAK] EXPORT TIM1_CC_IRQHandler [WEAK] EXPORT TIM2_IRQHandler [WEAK] EXPORT TIM3_IRQHandler [WEAK] EXPORT TIM4_IRQHandler [WEAK] EXPORT I2C1_EV_IRQHandler [WEAK] EXPORT I2C1_ER_IRQHandler [WEAK] EXPORT I2C2_EV_IRQHandler [WEAK] EXPORT I2C2_ER_IRQHandler [WEAK] EXPORT SPI1_IRQHandler [WEAK] EXPORT SPI2_IRQHandler [WEAK] EXPORT USART1_IRQHandler [WEAK] EXPORT USART2_IRQHandler [WEAK] EXPORT USART3_IRQHandler [WEAK] EXPORT EXTI15_10_IRQHandler [WEAK] EXPORT RTC_Alarm_IRQHandler [WEAK] EXPORT TIM8_BRK_TIM12_IRQHandler [WEAK] EXPORT TIM8_UP_TIM13_IRQHandler [WEAK] EXPORT TIM8_TRG_COM_TIM14_IRQHandler [WEAK] EXPORT TIM8_CC_IRQHandler [WEAK] EXPORT DMA1_Stream7_IRQHandler [WEAK] EXPORT FMC_IRQHandler [WEAK] EXPORT SDMMC1_IRQHandler [WEAK] EXPORT TIM5_IRQHandler [WEAK] EXPORT SPI3_IRQHandler [WEAK] EXPORT UART4_IRQHandler [WEAK] EXPORT UART5_IRQHandler [WEAK] EXPORT TIM6_DAC_IRQHandler [WEAK] EXPORT TIM7_IRQHandler [WEAK] EXPORT DMA2_Stream0_IRQHandler [WEAK] EXPORT DMA2_Stream1_IRQHandler [WEAK] EXPORT DMA2_Stream2_IRQHandler [WEAK] EXPORT DMA2_Stream3_IRQHandler [WEAK] EXPORT DMA2_Stream4_IRQHandler [WEAK] EXPORT ETH_IRQHandler [WEAK] EXPORT ETH_WKUP_IRQHandler [WEAK] EXPORT FDCAN_CAL_IRQHandler [WEAK] EXPORT DMA2_Stream5_IRQHandler [WEAK] EXPORT DMA2_Stream6_IRQHandler [WEAK] EXPORT DMA2_Stream7_IRQHandler [WEAK] EXPORT USART6_IRQHandler [WEAK] EXPORT I2C3_EV_IRQHandler [WEAK] EXPORT I2C3_ER_IRQHandler [WEAK] EXPORT OTG_HS_EP1_OUT_IRQHandler [WEAK] EXPORT OTG_HS_EP1_IN_IRQHandler [WEAK] EXPORT OTG_HS_WKUP_IRQHandler [WEAK] EXPORT OTG_HS_IRQHandler [WEAK] EXPORT DCMI_IRQHandler [WEAK] EXPORT RNG_IRQHandler [WEAK] EXPORT FPU_IRQHandler [WEAK] EXPORT UART7_IRQHandler [WEAK] EXPORT UART8_IRQHandler [WEAK] EXPORT SPI4_IRQHandler [WEAK] EXPORT SPI5_IRQHandler [WEAK] EXPORT SPI6_IRQHandler [WEAK] EXPORT SAI1_IRQHandler [WEAK] EXPORT LTDC_IRQHandler [WEAK] EXPORT LTDC_ER_IRQHandler [WEAK] EXPORT DMA2D_IRQHandler [WEAK] EXPORT SAI2_IRQHandler [WEAK] EXPORT QUADSPI_IRQHandler [WEAK] EXPORT LPTIM1_IRQHandler [WEAK] EXPORT CEC_IRQHandler [WEAK] EXPORT I2C4_EV_IRQHandler [WEAK] EXPORT I2C4_ER_IRQHandler [WEAK] EXPORT SPDIF_RX_IRQHandler [WEAK] EXPORT OTG_FS_EP1_OUT_IRQHandler [WEAK] EXPORT OTG_FS_EP1_IN_IRQHandler [WEAK] EXPORT OTG_FS_WKUP_IRQHandler [WEAK] EXPORT OTG_FS_IRQHandler [WEAK] EXPORT DMAMUX1_OVR_IRQHandler [WEAK] EXPORT HRTIM1_Master_IRQHandler [WEAK] EXPORT HRTIM1_TIMA_IRQHandler [WEAK] EXPORT HRTIM1_TIMB_IRQHandler [WEAK] EXPORT HRTIM1_TIMC_IRQHandler [WEAK] EXPORT HRTIM1_TIMD_IRQHandler [WEAK] EXPORT HRTIM1_TIME_IRQHandler [WEAK] EXPORT HRTIM1_FLT_IRQHandler [WEAK] EXPORT DFSDM1_FLT0_IRQHandler [WEAK] EXPORT DFSDM1_FLT1_IRQHandler [WEAK] EXPORT DFSDM1_FLT2_IRQHandler [WEAK] EXPORT DFSDM1_FLT3_IRQHandler [WEAK] EXPORT SAI3_IRQHandler [WEAK] EXPORT SWPMI1_IRQHandler [WEAK] EXPORT TIM15_IRQHandler [WEAK] EXPORT TIM16_IRQHandler [WEAK] EXPORT TIM17_IRQHandler [WEAK] EXPORT MDIOS_WKUP_IRQHandler [WEAK] EXPORT MDIOS_IRQHandler [WEAK] EXPORT JPEG_IRQHandler [WEAK] EXPORT MDMA_IRQHandler [WEAK] EXPORT SDMMC2_IRQHandler [WEAK] EXPORT HSEM1_IRQHandler [WEAK] EXPORT ADC3_IRQHandler [WEAK] EXPORT DMAMUX2_OVR_IRQHandler [WEAK] EXPORT BDMA_Channel0_IRQHandler [WEAK] EXPORT BDMA_Channel1_IRQHandler [WEAK] EXPORT BDMA_Channel2_IRQHandler [WEAK] EXPORT BDMA_Channel3_IRQHandler [WEAK] EXPORT BDMA_Channel4_IRQHandler [WEAK] EXPORT BDMA_Channel5_IRQHandler [WEAK] EXPORT BDMA_Channel6_IRQHandler [WEAK] EXPORT BDMA_Channel7_IRQHandler [WEAK] EXPORT COMP1_IRQHandler [WEAK] EXPORT LPTIM2_IRQHandler [WEAK] EXPORT LPTIM3_IRQHandler [WEAK] EXPORT LPTIM4_IRQHandler [WEAK] EXPORT LPTIM5_IRQHandler [WEAK] EXPORT LPUART1_IRQHandler [WEAK] EXPORT CRS_IRQHandler [WEAK] EXPORT SAI4_IRQHandler [WEAK] EXPORT WAKEUP_PIN_IRQHandler [WEAK] EXPORT Reserved42_IRQHandler [WEAK] EXPORT Reserved64_IRQHandler [WEAK] EXPORT Reserved65_IRQHandler [WEAK] EXPORT Reserved66_IRQHandler [WEAK] EXPORT Reserved67_IRQHandler [WEAK] EXPORT Reserved79_IRQHandler [WEAK] EXPORT Reserved124_IRQHandler [WEAK] EXPORT Reserved123_IRQHandler [WEAK] EXPORT Reserved126_IRQHandler [WEAK] EXPORT Reserved143_IRQHandler [WEAK] EXPORT Reserved145_IRQHandler [WEAK] EXPORT Reserved147_IRQHandler [WEAK] EXPORT Reserved148_IRQHandler [WEAK] WWDG_IRQHandler PVD_AVD_IRQHandler TAMP_STAMP_IRQHandler RTC_WKUP_IRQHandler FLASH_IRQHandler RCC_IRQHandler EXTI0_IRQHandler EXTI1_IRQHandler EXTI2_IRQHandler EXTI3_IRQHandler EXTI4_IRQHandler DMA1_Stream0_IRQHandler DMA1_Stream1_IRQHandler DMA1_Stream2_IRQHandler DMA1_Stream3_IRQHandler DMA1_Stream4_IRQHandler DMA1_Stream5_IRQHandler DMA1_Stream6_IRQHandler ADC_IRQHandler FDCAN1_IT0_IRQHandler FDCAN2_IT0_IRQHandler FDCAN1_IT1_IRQHandler FDCAN2_IT1_IRQHandler EXTI9_5_IRQHandler TIM1_BRK_IRQHandler TIM1_UP_IRQHandler TIM1_TRG_COM_IRQHandler TIM1_CC_IRQHandler TIM2_IRQHandler TIM3_IRQHandler TIM4_IRQHandler I2C1_EV_IRQHandler I2C1_ER_IRQHandler I2C2_EV_IRQHandler I2C2_ER_IRQHandler SPI1_IRQHandler SPI2_IRQHandler USART1_IRQHandler USART2_IRQHandler USART3_IRQHandler EXTI15_10_IRQHandler RTC_Alarm_IRQHandler TIM8_BRK_TIM12_IRQHandler TIM8_UP_TIM13_IRQHandler TIM8_TRG_COM_TIM14_IRQHandler TIM8_CC_IRQHandler DMA1_Stream7_IRQHandler FMC_IRQHandler SDMMC1_IRQHandler TIM5_IRQHandler SPI3_IRQHandler UART4_IRQHandler UART5_IRQHandler TIM6_DAC_IRQHandler TIM7_IRQHandler DMA2_Stream0_IRQHandler DMA2_Stream1_IRQHandler DMA2_Stream2_IRQHandler DMA2_Stream3_IRQHandler DMA2_Stream4_IRQHandler ETH_IRQHandler ETH_WKUP_IRQHandler FDCAN_CAL_IRQHandler DMA2_Stream5_IRQHandler DMA2_Stream6_IRQHandler DMA2_Stream7_IRQHandler USART6_IRQHandler I2C3_EV_IRQHandler I2C3_ER_IRQHandler OTG_HS_EP1_OUT_IRQHandler OTG_HS_EP1_IN_IRQHandler OTG_HS_WKUP_IRQHandler OTG_HS_IRQHandler DCMI_IRQHandler RNG_IRQHandler FPU_IRQHandler UART7_IRQHandler UART8_IRQHandler SPI4_IRQHandler SPI5_IRQHandler SPI6_IRQHandler SAI1_IRQHandler LTDC_IRQHandler LTDC_ER_IRQHandler DMA2D_IRQHandler SAI2_IRQHandler QUADSPI_IRQHandler LPTIM1_IRQHandler CEC_IRQHandler I2C4_EV_IRQHandler I2C4_ER_IRQHandler SPDIF_RX_IRQHandler OTG_FS_EP1_OUT_IRQHandler OTG_FS_EP1_IN_IRQHandler OTG_FS_WKUP_IRQHandler OTG_FS_IRQHandler DMAMUX1_OVR_IRQHandler HRTIM1_Master_IRQHandler HRTIM1_TIMA_IRQHandler HRTIM1_TIMB_IRQHandler HRTIM1_TIMC_IRQHandler HRTIM1_TIMD_IRQHandler HRTIM1_TIME_IRQHandler HRTIM1_FLT_IRQHandler DFSDM1_FLT0_IRQHandler DFSDM1_FLT1_IRQHandler DFSDM1_FLT2_IRQHandler DFSDM1_FLT3_IRQHandler SAI3_IRQHandler SWPMI1_IRQHandler TIM15_IRQHandler TIM16_IRQHandler TIM17_IRQHandler MDIOS_WKUP_IRQHandler MDIOS_IRQHandler JPEG_IRQHandler MDMA_IRQHandler SDMMC2_IRQHandler HSEM1_IRQHandler ADC3_IRQHandler DMAMUX2_OVR_IRQHandler BDMA_Channel0_IRQHandler BDMA_Channel1_IRQHandler BDMA_Channel2_IRQHandler BDMA_Channel3_IRQHandler BDMA_Channel4_IRQHandler BDMA_Channel5_IRQHandler BDMA_Channel6_IRQHandler BDMA_Channel7_IRQHandler COMP1_IRQHandler LPTIM2_IRQHandler LPTIM3_IRQHandler LPTIM4_IRQHandler LPTIM5_IRQHandler LPUART1_IRQHandler CRS_IRQHandler SAI4_IRQHandler WAKEUP_PIN_IRQHandler Reserved42_IRQHandler Reserved64_IRQHandler Reserved65_IRQHandler Reserved66_IRQHandler Reserved67_IRQHandler Reserved79_IRQHandler Reserved124_IRQHandler Reserved123_IRQHandler Reserved126_IRQHandler Reserved143_IRQHandler Reserved145_IRQHandler Reserved147_IRQHandler Reserved148_IRQHandler IMPORT assert_failed LDR r0,=str_Undefined MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_Undefined DCB "Undefined" ALIGN ENDP ALIGN ; make sure the end of this section is aligned ;****************************************************************************** ; The function expected of the C library startup code for defining the stack ; and heap memory locations. For the C library version of the startup code, ; provide this function so that the C library initialization code can find out ; the location of the stack and heap. ; IF :DEF: __MICROLIB EXPORT __initial_sp EXPORT __stack_limit EXPORT __heap_base EXPORT __heap_limit ELSE IMPORT __use_two_region_memory EXPORT __user_initial_stackheap __user_initial_stackheap PROC LDR R0, =__heap_base LDR R1, =__stack_limit LDR R2, =__heap_limit LDR R3, =__stack_base BX LR ENDP ENDIF ALIGN ; make sure the end of this section is aligned END ; end of module ================================================ FILE: 3rd_party/nucleo-h743zi/gnu/nucleo-h743zi.ld ================================================ /***************************************************************************** * Product: Linker script for STM32H743xx, GNU-ARM linker * Last Updated for Version: 6.1.0 * Date of the Last Update: 2018-01-30 * * Q u a n t u m L e a P s * --------------------------- * innovating embedded systems * * Copyright (C) Quantum Leaps, LLC. All rights reserved. * * This program is open source software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Alternatively, this program may be distributed and modified under the * terms of Quantum Leaps commercial licenses, which expressly supersede * the GNU General Public License and are specifically designed for * licensees interested in retaining the proprietary status of their code. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Contact information: * https://state-machine.com * mailto:info@state-machine.com *****************************************************************************/ OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(Reset_Handler) /* entry Point */ MEMORY { /* memory map of STM32F746NG */ ROM (rx) : ORIGIN = 0x08000000, LENGTH = 2048K RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 512K } /* The size of the stack used by the application. NOTE: you need to adjust */ STACK_SIZE = 2048; /* The size of the heap used by the application. NOTE: you need to adjust */ HEAP_SIZE = 0; SECTIONS { .isr_vector : { /* the vector table goes FIRST into ROM */ KEEP(*(.isr_vector)) /* vector table */ . = ALIGN(4); } >ROM .text : { /* code and constants */ . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); } >ROM .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >ROM .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >ROM .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(.fini_array*)) KEEP (*(SORT(.fini_array.*))) PROVIDE_HIDDEN (__fini_array_end = .); } >ROM _etext = .; /* global symbols at end of code */ .stack : { __stack_start__ = .; . = . + STACK_SIZE; . = ALIGN(4); __stack_end__ = .; } >RAM .data : AT (_etext) { __data_load = LOADADDR (.data); __data_start = .; *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); __data_end__ = .; _edata = __data_end__; } >RAM .bss : { __bss_start__ = .; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = .; } >RAM __exidx_start = .; .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM __exidx_end = .; PROVIDE ( end = _ebss ); PROVIDE ( _end = _ebss ); PROVIDE ( __end__ = _ebss ); .heap : { __heap_start__ = .; . = . + HEAP_SIZE; . = ALIGN(4); __heap_end__ = .; } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } } ================================================ FILE: 3rd_party/nucleo-h743zi/gnu/startup_stm32h743xx.c ================================================ /* File: startup_stm32h743xx.c for GNU-ARM * Purpose: startup file for STM32H743xx Cortex-M7 device. * Should be used with GCC 'GNU Tools ARM Embedded' * Version: CMSIS 5.0.1 * Date: 2017-09-13 * * Modified by Quantum Leaps: * - Added relocating of the Vector Table to free up the 256B region at 0x0 * for NULL-pointer protection by the MPU. * - Modified all exception handlers to branch to assert_failed() * instead of locking up the CPU inside an endless loop. * * Created from the CMSIS template for the specified device * Quantum Leaps, www.state-machine.com * * NOTE: * The function assert_failed defined at the end of this file defines * the error/assertion handling policy for the application and might * need to be customized for each project. This function is defined in * assembly to re-set the stack pointer, in case it is corrupted by the * time assert_failed is called. */ /* start and end of stack defined in the linker script ---------------------*/ /*extern int __stack_start__;*/ extern int __stack_end__; /* Weak prototypes for error handlers --------------------------------------*/ /** * \note * The function assert_failed defined at the end of this file defines * the error/assertion handling policy for the application and might * need to be customized for each project. This function is defined in * assembly to avoid accessing the stack, which might be corrupted by * the time assert_failed is called. */ __attribute__ ((naked, noreturn)) void assert_failed(char const *module, int loc); /* Function prototypes -----------------------------------------------------*/ void Default_Handler(void); /* Default empty handler */ void Reset_Handler(void); /* Reset Handler */ void SystemInit(void); /* CMSIS system initialization */ /*---------------------------------------------------------------------------- * weak aliases for each Exception handler to the Default_Handler. * Any function with the same name will override these definitions. */ /* Cortex-M Processor fault exceptions... */ void NMI_Handler (void) __attribute__ ((weak)); void HardFault_Handler (void) __attribute__ ((weak)); void MemManage_Handler (void) __attribute__ ((weak)); void BusFault_Handler (void) __attribute__ ((weak)); void UsageFault_Handler (void) __attribute__ ((weak)); /* Cortex-M Processor non-fault exceptions... */ void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); void DebugMon_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); /* external interrupts... */ void WWDG_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void PVD_AVD_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TAMP_STAMP_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void RTC_WKUP_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void FLASH_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void RCC_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void EXTI0_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void EXTI1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void EXTI2_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void EXTI3_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void EXTI4_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA1_Stream0_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA1_Stream1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA1_Stream2_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA1_Stream3_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA1_Stream4_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA1_Stream5_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA1_Stream6_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void ADC_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void FDCAN1_IT0_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void FDCAN2_IT0_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void FDCAN1_IT1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void FDCAN2_IT1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void EXTI9_5_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM1_BRK_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM1_UP_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM1_TRG_COM_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM1_CC_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM2_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM3_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM4_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void I2C1_EV_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void I2C1_ER_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void I2C2_EV_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void I2C2_ER_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void SPI1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void SPI2_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void USART1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void USART2_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void USART3_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void EXTI15_10_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void RTC_Alarm_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM8_BRK_TIM12_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM8_UP_TIM13_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM8_TRG_COM_TIM14_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM8_CC_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA1_Stream7_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void FMC_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void SDMMC1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM5_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void SPI3_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void UART4_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void UART5_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM6_DAC_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM7_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA2_Stream0_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA2_Stream1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA2_Stream2_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA2_Stream3_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA2_Stream4_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void ETH_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void ETH_WKUP_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void FDCAN_CAL_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA2_Stream5_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA2_Stream6_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA2_Stream7_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void USART6_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void I2C3_EV_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void I2C3_ER_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void OTG_HS_EP1_OUT_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void OTG_HS_EP1_IN_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void OTG_HS_WKUP_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void OTG_HS_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DCMI_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void RNG_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void FPU_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void UART7_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void UART8_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void SPI4_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void SPI5_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void SPI6_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void SAI1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void LTDC_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void LTDC_ER_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMA2D_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void SAI2_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void QUADSPI_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void LPTIM1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void CEC_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void I2C4_EV_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void I2C4_ER_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void SPDIF_RX_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void OTG_FS_EP1_OUT_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void OTG_FS_EP1_IN_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void OTG_FS_WKUP_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void OTG_FS_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMAMUX1_OVR_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void HRTIM1_Master_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void HRTIM1_TIMA_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void HRTIM1_TIMB_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void HRTIM1_TIMC_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void HRTIM1_TIMD_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void HRTIM1_TIME_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void HRTIM1_FLT_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DFSDM1_FLT0_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DFSDM1_FLT1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DFSDM1_FLT2_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DFSDM1_FLT3_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void SAI3_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void SWPMI1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM15_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM16_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void TIM17_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void MDIOS_WKUP_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void MDIOS_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void JPEG_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void MDMA_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void SDMMC2_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void HSEM1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void ADC3_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void DMAMUX2_OVR_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void BDMA_Channel0_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void BDMA_Channel1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void BDMA_Channel2_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void BDMA_Channel3_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void BDMA_Channel4_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void BDMA_Channel5_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void BDMA_Channel6_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void BDMA_Channel7_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void COMP1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void LPTIM2_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void LPTIM3_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void LPTIM4_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void LPTIM5_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void LPUART1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void CRS_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void SAI4_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void WAKEUP_PIN_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved42_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved64_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved65_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved66_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved67_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved79_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved124_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved123_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved126_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved143_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved145_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved147_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved148_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); /*..........................................................................*/ __attribute__ ((section(".isr_vector"))) int const g_pfnVectors[] = { (int)&__stack_end__, /* Top of Stack */ (int)&Reset_Handler, /* Reset Handler */ (int)&NMI_Handler, /* NMI Handler */ (int)&HardFault_Handler, /* Hard Fault Handler */ (int)&MemManage_Handler, /* The MPU fault handler */ (int)&BusFault_Handler, /* The bus fault handler */ (int)&UsageFault_Handler, /* The usage fault handler */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&SVC_Handler, /* SVCall handler */ (int)&DebugMon_Handler, /* Debug monitor handler */ (int)&Default_Handler, /* Reserved */ (int)&PendSV_Handler, /* The PendSV handler */ (int)&SysTick_Handler, /* The SysTick handler */ /* IRQ handlers... */ (int)&WWDG_IRQHandler, /* [ 0] Window WatchDog Interrupt ( wwdg1_it) */ (int)&PVD_AVD_IRQHandler, /* [ 1] PVD/AVD through EXTI Line detection */ (int)&TAMP_STAMP_IRQHandler, /* [ 2] Tamper and TimeStamps through EXTI line */ (int)&RTC_WKUP_IRQHandler, /* [ 3] RTC Wakeup through the EXTI line */ (int)&FLASH_IRQHandler, /* [ 4] FLASH */ (int)&RCC_IRQHandler, /* [ 5] RCC */ (int)&EXTI0_IRQHandler, /* [ 6] EXTI Line0 */ (int)&EXTI1_IRQHandler, /* [ 7] EXTI Line1 */ (int)&EXTI2_IRQHandler, /* [ 8] EXTI Line2 */ (int)&EXTI3_IRQHandler, /* [ 9] EXTI Line3 */ (int)&EXTI4_IRQHandler, /* [10] EXTI Line4 */ (int)&DMA1_Stream0_IRQHandler, /* [11] DMA1 Stream 0 */ (int)&DMA1_Stream1_IRQHandler, /* [12] DMA1 Stream 1 */ (int)&DMA1_Stream2_IRQHandler, /* [13] DMA1 Stream 2 */ (int)&DMA1_Stream3_IRQHandler, /* [14] DMA1 Stream 3 */ (int)&DMA1_Stream4_IRQHandler, /* [15] DMA1 Stream 4 */ (int)&DMA1_Stream5_IRQHandler, /* [16] DMA1 Stream 5 */ (int)&DMA1_Stream6_IRQHandler, /* [17] DMA1 Stream 6 */ (int)&ADC_IRQHandler, /* [18] ADC1, ADC2 */ (int)&FDCAN1_IT0_IRQHandler, /* [19] FDCAN1 interrupt line 0 */ (int)&FDCAN2_IT0_IRQHandler, /* [20] FDCAN2 interrupt line 0 */ (int)&FDCAN1_IT1_IRQHandler, /* [21] FDCAN1 interrupt line 1 */ (int)&FDCAN2_IT1_IRQHandler, /* [22] FDCAN2 interrupt line 1 */ (int)&EXTI9_5_IRQHandler, /* [23] External Line[9:5]s */ (int)&TIM1_BRK_IRQHandler, /* [24] TIM1 Break interrupt */ (int)&TIM1_UP_IRQHandler, /* [25] TIM1 Update */ (int)&TIM1_TRG_COM_IRQHandler, /* [26] TIM1 Trigger and Commutation Interrupt */ (int)&TIM1_CC_IRQHandler, /* [27] TIM1 Capture Compare */ (int)&TIM2_IRQHandler, /* [28] TIM2 */ (int)&TIM3_IRQHandler, /* [29] TIM3 */ (int)&TIM4_IRQHandler, /* [30] TIM4 */ (int)&I2C1_EV_IRQHandler, /* [31] I2C1 Event */ (int)&I2C1_ER_IRQHandler, /* [32] I2C1 Error */ (int)&I2C2_EV_IRQHandler, /* [33] I2C2 Event */ (int)&I2C2_ER_IRQHandler, /* [34] I2C2 Error */ (int)&SPI1_IRQHandler, /* [35] SPI1 */ (int)&SPI2_IRQHandler, /* [36] SPI2 */ (int)&USART1_IRQHandler, /* [37] USART1 */ (int)&USART2_IRQHandler, /* [38] USART2 */ (int)&USART3_IRQHandler, /* [39] USART3 */ (int)&EXTI15_10_IRQHandler, /* [40] External Line[15:10] */ (int)&RTC_Alarm_IRQHandler, /* [41] RTC Alarm (A and B) through EXTI Line */ (int)&Reserved42_IRQHandler, /* [42] Reserved */ (int)&TIM8_BRK_TIM12_IRQHandler,/* [43] TIM8 Break Interrupt and TIM12 global interrupt */ (int)&TIM8_UP_TIM13_IRQHandler, /* [44] TIM8 Update Interrupt and TIM13 global interrupt */ (int)&TIM8_TRG_COM_TIM14_IRQHandler,/* [45] TIM8 Trigger and Commutation Interrupt and TIM14 glob */ (int)&TIM8_CC_IRQHandler, /* [46] TIM8 Capture Compare Interrupt */ (int)&DMA1_Stream7_IRQHandler, /* [47] DMA1 Stream7 */ (int)&FMC_IRQHandler, /* [48] FMC */ (int)&SDMMC1_IRQHandler, /* [49] SDMMC1 */ (int)&TIM5_IRQHandler, /* [50] TIM5 */ (int)&SPI3_IRQHandler, /* [51] SPI3 */ (int)&UART4_IRQHandler, /* [52] UART4 */ (int)&UART5_IRQHandler, /* [53] UART5 */ (int)&TIM6_DAC_IRQHandler, /* [54] TIM6 and DAC1&2 underrun errors */ (int)&TIM7_IRQHandler, /* [55] TIM7 */ (int)&DMA2_Stream0_IRQHandler, /* [56] DMA2 Stream 0 */ (int)&DMA2_Stream1_IRQHandler, /* [57] DMA2 Stream 1 */ (int)&DMA2_Stream2_IRQHandler, /* [58] DMA2 Stream 2 */ (int)&DMA2_Stream3_IRQHandler, /* [59] DMA2 Stream 3 */ (int)&DMA2_Stream4_IRQHandler, /* [60] DMA2 Stream 4 */ (int)Ð_IRQHandler, /* [61] Ethernet */ (int)Ð_WKUP_IRQHandler, /* [62] Ethernet Wakeup through EXTI line */ (int)&FDCAN_CAL_IRQHandler, /* [63] FDCAN calibration unit interrupt */ (int)&Reserved64_IRQHandler, /* [64] Reserved */ (int)&Reserved65_IRQHandler, /* [65] Reserved */ (int)&Reserved66_IRQHandler, /* [66] Reserved */ (int)&Reserved67_IRQHandler, /* [67] Reserved */ (int)&DMA2_Stream5_IRQHandler, /* [68] DMA2 Stream 5 */ (int)&DMA2_Stream6_IRQHandler, /* [69] DMA2 Stream 6 */ (int)&DMA2_Stream7_IRQHandler, /* [70] DMA2 Stream 7 */ (int)&USART6_IRQHandler, /* [71] USART6 */ (int)&I2C3_EV_IRQHandler, /* [72] I2C3 event */ (int)&I2C3_ER_IRQHandler, /* [73] I2C3 error */ (int)&OTG_HS_EP1_OUT_IRQHandler,/* [74] USB OTG HS End Point 1 Out */ (int)&OTG_HS_EP1_IN_IRQHandler, /* [75] USB OTG HS End Point 1 In */ (int)&OTG_HS_WKUP_IRQHandler, /* [76] USB OTG HS Wakeup through EXTI */ (int)&OTG_HS_IRQHandler, /* [77] USB OTG HS */ (int)&DCMI_IRQHandler, /* [78] DCMI */ (int)&Reserved79_IRQHandler, /* [79] Reserved */ (int)&RNG_IRQHandler, /* [80] Rng */ (int)&FPU_IRQHandler, /* [81] FPU */ (int)&UART7_IRQHandler, /* [82] UART7 */ (int)&UART8_IRQHandler, /* [83] UART8 */ (int)&SPI4_IRQHandler, /* [84] SPI4 */ (int)&SPI5_IRQHandler, /* [85] SPI5 */ (int)&SPI6_IRQHandler, /* [86] SPI6 */ (int)&SAI1_IRQHandler, /* [87] SAI1 */ (int)<DC_IRQHandler, /* [88] LTDC */ (int)<DC_ER_IRQHandler, /* [89] LTDC error */ (int)&DMA2D_IRQHandler, /* [90] DMA2D */ (int)&SAI2_IRQHandler, /* [91] SAI2 */ (int)&QUADSPI_IRQHandler, /* [92] QUADSPI */ (int)&LPTIM1_IRQHandler, /* [93] LPTIM1 */ (int)&CEC_IRQHandler, /* [94] HDMI_CEC */ (int)&I2C4_EV_IRQHandler, /* [95] I2C4 Event */ (int)&I2C4_ER_IRQHandler, /* [96] I2C4 Error */ (int)&SPDIF_RX_IRQHandler, /* [97] SPDIF_RX */ (int)&OTG_FS_EP1_OUT_IRQHandler,/* [98] USB OTG FS End Point 1 Out */ (int)&OTG_FS_EP1_IN_IRQHandler, /* [99] USB OTG FS End Point 1 In */ (int)&OTG_FS_WKUP_IRQHandler, /* [100] USB OTG FS Wakeup through EXTI */ (int)&OTG_FS_IRQHandler, /* [101] USB OTG FS */ (int)&DMAMUX1_OVR_IRQHandler, /* [102] DMAMUX1 Overrun interrupt */ (int)&HRTIM1_Master_IRQHandler, /* [103] HRTIM Master Timer global Interrupts */ (int)&HRTIM1_TIMA_IRQHandler, /* [104] HRTIM Timer A global Interrupt */ (int)&HRTIM1_TIMB_IRQHandler, /* [105] HRTIM Timer B global Interrupt */ (int)&HRTIM1_TIMC_IRQHandler, /* [106] HRTIM Timer C global Interrupt */ (int)&HRTIM1_TIMD_IRQHandler, /* [107] HRTIM Timer D global Interrupt */ (int)&HRTIM1_TIME_IRQHandler, /* [108] HRTIM Timer E global Interrupt */ (int)&HRTIM1_FLT_IRQHandler, /* [109] HRTIM Fault global Interrupt */ (int)&DFSDM1_FLT0_IRQHandler, /* [110] DFSDM Filter0 Interrupt */ (int)&DFSDM1_FLT1_IRQHandler, /* [111] DFSDM Filter1 Interrupt */ (int)&DFSDM1_FLT2_IRQHandler, /* [112] DFSDM Filter2 Interrupt */ (int)&DFSDM1_FLT3_IRQHandler, /* [113] DFSDM Filter3 Interrupt */ (int)&SAI3_IRQHandler, /* [114] SAI3 global Interrupt */ (int)&SWPMI1_IRQHandler, /* [115] Serial Wire Interface 1 global interrupt */ (int)&TIM15_IRQHandler, /* [116] TIM15 global Interrupt */ (int)&TIM16_IRQHandler, /* [117] TIM16 global Interrupt */ (int)&TIM17_IRQHandler, /* [118] TIM17 global Interrupt */ (int)&MDIOS_WKUP_IRQHandler, /* [119] MDIOS Wakeup Interrupt */ (int)&MDIOS_IRQHandler, /* [120] MDIOS global Interrupt */ (int)&JPEG_IRQHandler, /* [121] JPEG global Interrupt */ (int)&MDMA_IRQHandler, /* [122] MDMA global Interrupt */ (int)&Reserved123_IRQHandler, /* [123] Reserved */ (int)&SDMMC2_IRQHandler, /* [124] SDMMC2 global Interrupt */ (int)&HSEM1_IRQHandler, /* [125] HSEM1 global Interrupt */ (int)&Reserved126_IRQHandler, /* [126] Reserved */ (int)&ADC3_IRQHandler, /* [127] ADC3 global Interrupt */ (int)&DMAMUX2_OVR_IRQHandler, /* [128] DMAMUX Overrun interrupt */ (int)&BDMA_Channel0_IRQHandler, /* [129] BDMA Channel 0 global Interrupt */ (int)&BDMA_Channel1_IRQHandler, /* [130] BDMA Channel 1 global Interrupt */ (int)&BDMA_Channel2_IRQHandler, /* [131] BDMA Channel 2 global Interrupt */ (int)&BDMA_Channel3_IRQHandler, /* [132] BDMA Channel 3 global Interrupt */ (int)&BDMA_Channel4_IRQHandler, /* [133] BDMA Channel 4 global Interrupt */ (int)&BDMA_Channel5_IRQHandler, /* [134] BDMA Channel 5 global Interrupt */ (int)&BDMA_Channel6_IRQHandler, /* [135] BDMA Channel 6 global Interrupt */ (int)&BDMA_Channel7_IRQHandler, /* [136] BDMA Channel 7 global Interrupt */ (int)&COMP1_IRQHandler, /* [137] COMP1 global Interrupt */ (int)&LPTIM2_IRQHandler, /* [138] LP TIM2 global interrupt */ (int)&LPTIM3_IRQHandler, /* [139] LP TIM3 global interrupt */ (int)&LPTIM4_IRQHandler, /* [140] LP TIM4 global interrupt */ (int)&LPTIM5_IRQHandler, /* [141] LP TIM5 global interrupt */ (int)&LPUART1_IRQHandler, /* [142] LP UART1 interrupt */ (int)&Reserved143_IRQHandler, /* [143] Reserved */ (int)&CRS_IRQHandler, /* [144] Clock Recovery Global Interrupt */ (int)&Reserved145_IRQHandler, /* [145] Reserved */ (int)&SAI4_IRQHandler, /* [146] SAI4 global interrupt */ (int)&Reserved147_IRQHandler, /* [147] Reserved */ (int)&Reserved148_IRQHandler, /* [148] Reserved */ (int)&WAKEUP_PIN_IRQHandler, /* [149] Interrupt for all 6 wake-up pins */ }; /* reset handler -----------------------------------------------------------*/ __attribute__((naked)) void Reset_Handler(void); void Reset_Handler(void) { extern int main(void); extern int __libc_init_array(void); extern unsigned __data_start; /* start of .data in the linker script */ extern unsigned __data_end__; /* end of .data in the linker script */ extern unsigned const __data_load; /* initialization values for .data */ extern unsigned __bss_start__; /* start of .bss in the linker script */ extern unsigned __bss_end__; /* end of .bss in the linker script */ extern void software_init_hook(void) __attribute__((weak)); SystemInit(); /* CMSIS system initialization */ /* copy the data segment initializers from flash to RAM... */ unsigned const *src = &__data_load; unsigned *dst; for (dst = &__data_start; dst < &__data_end__; ++dst, ++src) { *dst = *src; } /* zero fill the .bss segment in RAM... */ for (dst = &__bss_start__; dst < &__bss_end__; ++dst) { *dst = 0; } /* init hook provided? */ if (&software_init_hook != (void (*)(void))(0)) { /* give control to the RTOS */ software_init_hook(); /* this will also call __libc_init_array */ } else { /* call all static constructors in C++ (harmless in C programs) */ __libc_init_array(); (void)main(); /* application's entry point; should never return! */ } /* the previous code should not return, but assert just in case... */ assert_failed("Reset_Handler", 1U); } /* fault exception handlers ------------------------------------------------*/ __attribute__((naked)) void NMI_Handler(void); void NMI_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("NMI_Handler", 1U); } /*..........................................................................*/ __attribute__((naked)) void HardFault_Handler(void); void HardFault_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("HardFault_Handler", 1U); } /*..........................................................................*/ __attribute__((naked)) void MemManage_Handler(void); void MemManage_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("MemManage_Handler", 1U); } /*..........................................................................*/ __attribute__((naked)) void BusFault_Handler(void); void BusFault_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("MemManage_Handler", 1U); } /*..........................................................................*/ __attribute__((naked)) void UsageFault_Handler(void); void UsageFault_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("BusFault_Handler", 1U); } /*..........................................................................*/ __attribute__((naked)) void Default_Handler(void); void Default_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("Default_Handler", 1U); } ================================================ FILE: 3rd_party/nucleo-h743zi/iar/startup_stm32h743xx.s ================================================ ;/***************************************************************************/ ; * @file startup_stm32h743xx.s for IAR ARM assembler ; * @brief CMSIS Cortex-M7 Core Device Startup File for STM32H743xx ; * @version CMSIS 5.9.0 ; * @date 1 Feb 2023 ; * ; * Modified by Quantum Leaps: ; * - Added relocating of the Vector Table to free up the 256B region at 0x0 ; * for NULL-pointer protection by the MPU. ; * - Modified all exception handlers to branch to assert_failed() ; * instead of locking up the CPU inside an endless loop. ; * ; * @description ; * Created from the CMSIS template for the specified device ; * Quantum Leaps, www.state-machine.com ; * MODULE ?cstartup ; Forward declaration of sections. SECTION CSTACK:DATA:NOROOT(3) SECTION .intvec:CODE:NOROOT(8) PUBLIC __vector_table PUBLIC __Vectors PUBLIC __Vectors_End PUBLIC __Vectors_Size ;****************************************************************************** ; The vector table. ; DATA __vector_table ; Initial Vector Table before relocation DCD sfe(CSTACK) DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU fault handler DCD BusFault_Handler ; Bus fault handler DCD UsageFault_Handler ; Usage fault handler DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD SVC_Handler ; SVCall handler DCD DebugMon_Handler ; Debug Monitor handler DCD Default_Handler ; Reserved DCD PendSV_Handler ; PendSV handler DCD SysTick_Handler ; SysTick handler ; IRQ handlers... DCD WWDG_IRQHandler ; [ 0] Window WatchDog Interrupt ( wwdg1_it) DCD PVD_AVD_IRQHandler ; [ 1] PVD/AVD through EXTI Line detection DCD TAMP_STAMP_IRQHandler ; [ 2] Tamper and TimeStamps through EXTI line DCD RTC_WKUP_IRQHandler ; [ 3] RTC Wakeup through the EXTI line DCD FLASH_IRQHandler ; [ 4] FLASH DCD RCC_IRQHandler ; [ 5] RCC DCD EXTI0_IRQHandler ; [ 6] EXTI Line0 DCD EXTI1_IRQHandler ; [ 7] EXTI Line1 DCD EXTI2_IRQHandler ; [ 8] EXTI Line2 DCD EXTI3_IRQHandler ; [ 9] EXTI Line3 DCD EXTI4_IRQHandler ; [10] EXTI Line4 DCD DMA1_Stream0_IRQHandler ; [11] DMA1 Stream 0 DCD DMA1_Stream1_IRQHandler ; [12] DMA1 Stream 1 DCD DMA1_Stream2_IRQHandler ; [13] DMA1 Stream 2 DCD DMA1_Stream3_IRQHandler ; [14] DMA1 Stream 3 DCD DMA1_Stream4_IRQHandler ; [15] DMA1 Stream 4 DCD DMA1_Stream5_IRQHandler ; [16] DMA1 Stream 5 DCD DMA1_Stream6_IRQHandler ; [17] DMA1 Stream 6 DCD ADC_IRQHandler ; [18] ADC1, ADC2 DCD FDCAN1_IT0_IRQHandler ; [19] FDCAN1 interrupt line 0 DCD FDCAN2_IT0_IRQHandler ; [20] FDCAN2 interrupt line 0 DCD FDCAN1_IT1_IRQHandler ; [21] FDCAN1 interrupt line 1 DCD FDCAN2_IT1_IRQHandler ; [22] FDCAN2 interrupt line 1 DCD EXTI9_5_IRQHandler ; [23] External Line[9:5]s DCD TIM1_BRK_IRQHandler ; [24] TIM1 Break interrupt DCD TIM1_UP_IRQHandler ; [25] TIM1 Update DCD TIM1_TRG_COM_IRQHandler ; [26] TIM1 Trigger and Commutation Interrupt DCD TIM1_CC_IRQHandler ; [27] TIM1 Capture Compare DCD TIM2_IRQHandler ; [28] TIM2 DCD TIM3_IRQHandler ; [29] TIM3 DCD TIM4_IRQHandler ; [30] TIM4 DCD I2C1_EV_IRQHandler ; [31] I2C1 Event DCD I2C1_ER_IRQHandler ; [32] I2C1 Error DCD I2C2_EV_IRQHandler ; [33] I2C2 Event DCD I2C2_ER_IRQHandler ; [34] I2C2 Error DCD SPI1_IRQHandler ; [35] SPI1 DCD SPI2_IRQHandler ; [36] SPI2 DCD USART1_IRQHandler ; [37] USART1 DCD USART2_IRQHandler ; [38] USART2 DCD USART3_IRQHandler ; [39] USART3 DCD EXTI15_10_IRQHandler ; [40] External Line[15:10] DCD RTC_Alarm_IRQHandler ; [41] RTC Alarm (A and B) through EXTI Line DCD Reserved42_IRQHandler ; [42] Reserved DCD TIM8_BRK_TIM12_IRQHandler ; [43] TIM8 Break Interrupt and TIM12 global interrupt DCD TIM8_UP_TIM13_IRQHandler ; [44] TIM8 Update Interrupt and TIM13 global interrupt DCD TIM8_TRG_COM_TIM14_IRQHandler;[45] TIM8 Trigger and Commutation Interrupt and TIM14 glob DCD TIM8_CC_IRQHandler ; [46] TIM8 Capture Compare Interrupt DCD DMA1_Stream7_IRQHandler ; [47] DMA1 Stream7 DCD FMC_IRQHandler ; [48] FMC DCD SDMMC1_IRQHandler ; [49] SDMMC1 DCD TIM5_IRQHandler ; [50] TIM5 DCD SPI3_IRQHandler ; [51] SPI3 DCD UART4_IRQHandler ; [52] UART4 DCD UART5_IRQHandler ; [53] UART5 DCD TIM6_DAC_IRQHandler ; [54] TIM6 and DAC1&2 underrun errors DCD TIM7_IRQHandler ; [55] TIM7 DCD DMA2_Stream0_IRQHandler ; [56] DMA2 Stream 0 DCD DMA2_Stream1_IRQHandler ; [57] DMA2 Stream 1 DCD DMA2_Stream2_IRQHandler ; [58] DMA2 Stream 2 DCD DMA2_Stream3_IRQHandler ; [59] DMA2 Stream 3 DCD DMA2_Stream4_IRQHandler ; [60] DMA2 Stream 4 DCD ETH_IRQHandler ; [61] Ethernet DCD ETH_WKUP_IRQHandler ; [62] Ethernet Wakeup through EXTI line DCD FDCAN_CAL_IRQHandler ; [63] FDCAN calibration unit interrupt DCD Reserved64_IRQHandler ; [64] Reserved DCD Reserved65_IRQHandler ; [65] Reserved DCD Reserved66_IRQHandler ; [66] Reserved DCD Reserved67_IRQHandler ; [67] Reserved DCD DMA2_Stream5_IRQHandler ; [68] DMA2 Stream 5 DCD DMA2_Stream6_IRQHandler ; [69] DMA2 Stream 6 DCD DMA2_Stream7_IRQHandler ; [70] DMA2 Stream 7 DCD USART6_IRQHandler ; [71] USART6 DCD I2C3_EV_IRQHandler ; [72] I2C3 event DCD I2C3_ER_IRQHandler ; [73] I2C3 error DCD OTG_HS_EP1_OUT_IRQHandler ; [74] USB OTG HS End Point 1 Out DCD OTG_HS_EP1_IN_IRQHandler ; [75] USB OTG HS End Point 1 In DCD OTG_HS_WKUP_IRQHandler ; [76] USB OTG HS Wakeup through EXTI DCD OTG_HS_IRQHandler ; [77] USB OTG HS DCD DCMI_IRQHandler ; [78] DCMI DCD Reserved79_IRQHandler ; [79] Reserved DCD RNG_IRQHandler ; [80] Rng DCD FPU_IRQHandler ; [81] FPU DCD UART7_IRQHandler ; [82] UART7 DCD UART8_IRQHandler ; [83] UART8 DCD SPI4_IRQHandler ; [84] SPI4 DCD SPI5_IRQHandler ; [85] SPI5 DCD SPI6_IRQHandler ; [86] SPI6 DCD SAI1_IRQHandler ; [87] SAI1 DCD LTDC_IRQHandler ; [88] LTDC DCD LTDC_ER_IRQHandler ; [89] LTDC error DCD DMA2D_IRQHandler ; [90] DMA2D DCD SAI2_IRQHandler ; [91] SAI2 DCD QUADSPI_IRQHandler ; [92] QUADSPI DCD LPTIM1_IRQHandler ; [93] LPTIM1 DCD CEC_IRQHandler ; [94] HDMI_CEC DCD I2C4_EV_IRQHandler ; [95] I2C4 Event DCD I2C4_ER_IRQHandler ; [96] I2C4 Error DCD SPDIF_RX_IRQHandler ; [97] SPDIF_RX DCD OTG_FS_EP1_OUT_IRQHandler ; [98] USB OTG FS End Point 1 Out DCD OTG_FS_EP1_IN_IRQHandler ; [99] USB OTG FS End Point 1 In DCD OTG_FS_WKUP_IRQHandler ; [100] USB OTG FS Wakeup through EXTI DCD OTG_FS_IRQHandler ; [101] USB OTG FS DCD DMAMUX1_OVR_IRQHandler ; [102] DMAMUX1 Overrun interrupt DCD HRTIM1_Master_IRQHandler ; [103] HRTIM Master Timer global Interrupts DCD HRTIM1_TIMA_IRQHandler ; [104] HRTIM Timer A global Interrupt DCD HRTIM1_TIMB_IRQHandler ; [105] HRTIM Timer B global Interrupt DCD HRTIM1_TIMC_IRQHandler ; [106] HRTIM Timer C global Interrupt DCD HRTIM1_TIMD_IRQHandler ; [107] HRTIM Timer D global Interrupt DCD HRTIM1_TIME_IRQHandler ; [108] HRTIM Timer E global Interrupt DCD HRTIM1_FLT_IRQHandler ; [109] HRTIM Fault global Interrupt DCD DFSDM1_FLT0_IRQHandler ; [110] DFSDM Filter0 Interrupt DCD DFSDM1_FLT1_IRQHandler ; [111] DFSDM Filter1 Interrupt DCD DFSDM1_FLT2_IRQHandler ; [112] DFSDM Filter2 Interrupt DCD DFSDM1_FLT3_IRQHandler ; [113] DFSDM Filter3 Interrupt DCD SAI3_IRQHandler ; [114] SAI3 global Interrupt DCD SWPMI1_IRQHandler ; [115] Serial Wire Interface 1 global interrupt DCD TIM15_IRQHandler ; [116] TIM15 global Interrupt DCD TIM16_IRQHandler ; [117] TIM16 global Interrupt DCD TIM17_IRQHandler ; [118] TIM17 global Interrupt DCD MDIOS_WKUP_IRQHandler ; [119] MDIOS Wakeup Interrupt DCD MDIOS_IRQHandler ; [120] MDIOS global Interrupt DCD JPEG_IRQHandler ; [121] JPEG global Interrupt DCD MDMA_IRQHandler ; [122] MDMA global Interrupt DCD Reserved123_IRQHandler ; [123] Reserved DCD SDMMC2_IRQHandler ; [124] SDMMC2 global Interrupt DCD HSEM1_IRQHandler ; [125] HSEM1 global Interrupt DCD Reserved126_IRQHandler ; [126] Reserved DCD ADC3_IRQHandler ; [127] ADC3 global Interrupt DCD DMAMUX2_OVR_IRQHandler ; [128] DMAMUX Overrun interrupt DCD BDMA_Channel0_IRQHandler ; [129] BDMA Channel 0 global Interrupt DCD BDMA_Channel1_IRQHandler ; [130] BDMA Channel 1 global Interrupt DCD BDMA_Channel2_IRQHandler ; [131] BDMA Channel 2 global Interrupt DCD BDMA_Channel3_IRQHandler ; [132] BDMA Channel 3 global Interrupt DCD BDMA_Channel4_IRQHandler ; [133] BDMA Channel 4 global Interrupt DCD BDMA_Channel5_IRQHandler ; [134] BDMA Channel 5 global Interrupt DCD BDMA_Channel6_IRQHandler ; [135] BDMA Channel 6 global Interrupt DCD BDMA_Channel7_IRQHandler ; [136] BDMA Channel 7 global Interrupt DCD COMP1_IRQHandler ; [137] COMP1 global Interrupt DCD LPTIM2_IRQHandler ; [138] LP TIM2 global interrupt DCD LPTIM3_IRQHandler ; [139] LP TIM3 global interrupt DCD LPTIM4_IRQHandler ; [140] LP TIM4 global interrupt DCD LPTIM5_IRQHandler ; [141] LP TIM5 global interrupt DCD LPUART1_IRQHandler ; [142] LP UART1 interrupt DCD Reserved143_IRQHandler ; [143] Reserved DCD CRS_IRQHandler ; [144] Clock Recovery Global Interrupt DCD Reserved145_IRQHandler ; [145] Reserved DCD SAI4_IRQHandler ; [146] SAI4 global interrupt DCD Reserved147_IRQHandler ; [147] Reserved DCD Reserved148_IRQHandler ; [148] Reserved DCD WAKEUP_PIN_IRQHandler ; [149] Interrupt for all 6 wake-up pins __Vectors_End __Vectors EQU __vector_table __Vectors_Size EQU __Vectors_End - __Vectors ;****************************************************************************** ; This is the code for exception handlers. ; SECTION .text:CODE:REORDER:NOROOT(2) ;****************************************************************************** ; This is the code that gets called when theessor first starts execution ; following a reset event. ; PUBWEAK Reset_Handler EXTERN SystemInit EXTERN __iar_program_start EXTERN assert_failed Reset_Handler LDR r0,=SystemInit ; CMSIS system initialization BLX r0 ; pre-fill the CSTACK with 0xDEADBEEF................... LDR r0,=0xDEADBEEF MOV r1,r0 LDR r2,=sfb(CSTACK) LDR r3,=sfe(CSTACK) Reset_stackInit_fill: STMIA r2!,{r0,r1} CMP r2,r3 BLT.N Reset_stackInit_fill LDR r0,=__iar_program_start ; IAR startup code BLX r0 ; __iar_program_start calls the main() function, which should not return, ; but just in case jump to assert_failed() if main returns. LDR r0,=str_EXIT MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_EXIT DCB "EXIT" ALIGNROM 2 ;****************************************************************************** PUBWEAK NMI_Handler NMI_Handler LDR r0,=str_NMI MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_NMI DCB "NMI" ALIGNROM 2 ;****************************************************************************** PUBWEAK HardFault_Handler HardFault_Handler LDR r0,=str_HardFault MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_HardFault DCB "HardFault" ALIGNROM 2 ;****************************************************************************** PUBWEAK MemManage_Handler MemManage_Handler LDR r0,=str_MemManage MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_MemManage DCB "MemManage" ALIGNROM 2 ;****************************************************************************** PUBWEAK BusFault_Handler BusFault_Handler LDR r0,=str_BusFault MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_BusFault DCB "BusFault" ALIGNROM 2 ;****************************************************************************** PUBWEAK UsageFault_Handler UsageFault_Handler LDR r0,=str_UsageFault MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_UsageFault DCB "UsageFault" ALIGNROM 2 ;****************************************************************************** ; ; Weak non-fault handlers... ; ;****************************************************************************** PUBWEAK SVC_Handler SVC_Handler LDR r0,=str_SVC MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_SVC DCB "SVC" ALIGNROM 2 ;****************************************************************************** PUBWEAK DebugMon_Handler DebugMon_Handler LDR r0,=str_DebugMon MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_DebugMon DCB "DebugMon" ALIGNROM 2 ;****************************************************************************** PUBWEAK PendSV_Handler PendSV_Handler LDR r0,=str_PendSV MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_PendSV DCB "PendSV" ALIGNROM 2 ;****************************************************************************** PUBWEAK SysTick_Handler SysTick_Handler LDR r0,=str_SysTick MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_SysTick DCB "SysTick" ALIGNROM 2 ;****************************************************************************** ; Weak IRQ handlers... ; PUBWEAK Default_Handler PUBWEAK WWDG_IRQHandler PUBWEAK PVD_AVD_IRQHandler PUBWEAK TAMP_STAMP_IRQHandler PUBWEAK RTC_WKUP_IRQHandler PUBWEAK FLASH_IRQHandler PUBWEAK RCC_IRQHandler PUBWEAK EXTI0_IRQHandler PUBWEAK EXTI1_IRQHandler PUBWEAK EXTI2_IRQHandler PUBWEAK EXTI3_IRQHandler PUBWEAK EXTI4_IRQHandler PUBWEAK DMA1_Stream0_IRQHandler PUBWEAK DMA1_Stream1_IRQHandler PUBWEAK DMA1_Stream2_IRQHandler PUBWEAK DMA1_Stream3_IRQHandler PUBWEAK DMA1_Stream4_IRQHandler PUBWEAK DMA1_Stream5_IRQHandler PUBWEAK DMA1_Stream6_IRQHandler PUBWEAK ADC_IRQHandler PUBWEAK FDCAN1_IT0_IRQHandler PUBWEAK FDCAN2_IT0_IRQHandler PUBWEAK FDCAN1_IT1_IRQHandler PUBWEAK FDCAN2_IT1_IRQHandler PUBWEAK EXTI9_5_IRQHandler PUBWEAK TIM1_BRK_IRQHandler PUBWEAK TIM1_UP_IRQHandler PUBWEAK TIM1_TRG_COM_IRQHandler PUBWEAK TIM1_CC_IRQHandler PUBWEAK TIM2_IRQHandler PUBWEAK TIM3_IRQHandler PUBWEAK TIM4_IRQHandler PUBWEAK I2C1_EV_IRQHandler PUBWEAK I2C1_ER_IRQHandler PUBWEAK I2C2_EV_IRQHandler PUBWEAK I2C2_ER_IRQHandler PUBWEAK SPI1_IRQHandler PUBWEAK SPI2_IRQHandler PUBWEAK USART1_IRQHandler PUBWEAK USART2_IRQHandler PUBWEAK USART3_IRQHandler PUBWEAK EXTI15_10_IRQHandler PUBWEAK RTC_Alarm_IRQHandler PUBWEAK TIM8_BRK_TIM12_IRQHandler PUBWEAK TIM8_UP_TIM13_IRQHandler PUBWEAK TIM8_TRG_COM_TIM14_IRQHandler PUBWEAK TIM8_CC_IRQHandler PUBWEAK DMA1_Stream7_IRQHandler PUBWEAK FMC_IRQHandler PUBWEAK SDMMC1_IRQHandler PUBWEAK TIM5_IRQHandler PUBWEAK SPI3_IRQHandler PUBWEAK UART4_IRQHandler PUBWEAK UART5_IRQHandler PUBWEAK TIM6_DAC_IRQHandler PUBWEAK TIM7_IRQHandler PUBWEAK DMA2_Stream0_IRQHandler PUBWEAK DMA2_Stream1_IRQHandler PUBWEAK DMA2_Stream2_IRQHandler PUBWEAK DMA2_Stream3_IRQHandler PUBWEAK DMA2_Stream4_IRQHandler PUBWEAK ETH_IRQHandler PUBWEAK ETH_WKUP_IRQHandler PUBWEAK FDCAN_CAL_IRQHandler PUBWEAK DMA2_Stream5_IRQHandler PUBWEAK DMA2_Stream6_IRQHandler PUBWEAK DMA2_Stream7_IRQHandler PUBWEAK USART6_IRQHandler PUBWEAK I2C3_EV_IRQHandler PUBWEAK I2C3_ER_IRQHandler PUBWEAK OTG_HS_EP1_OUT_IRQHandler PUBWEAK OTG_HS_EP1_IN_IRQHandler PUBWEAK OTG_HS_WKUP_IRQHandler PUBWEAK OTG_HS_IRQHandler PUBWEAK DCMI_IRQHandler PUBWEAK RNG_IRQHandler PUBWEAK FPU_IRQHandler PUBWEAK UART7_IRQHandler PUBWEAK UART8_IRQHandler PUBWEAK SPI4_IRQHandler PUBWEAK SPI5_IRQHandler PUBWEAK SPI6_IRQHandler PUBWEAK SAI1_IRQHandler PUBWEAK LTDC_IRQHandler PUBWEAK LTDC_ER_IRQHandler PUBWEAK DMA2D_IRQHandler PUBWEAK SAI2_IRQHandler PUBWEAK QUADSPI_IRQHandler PUBWEAK LPTIM1_IRQHandler PUBWEAK CEC_IRQHandler PUBWEAK I2C4_EV_IRQHandler PUBWEAK I2C4_ER_IRQHandler PUBWEAK SPDIF_RX_IRQHandler PUBWEAK OTG_FS_EP1_OUT_IRQHandler PUBWEAK OTG_FS_EP1_IN_IRQHandler PUBWEAK OTG_FS_WKUP_IRQHandler PUBWEAK OTG_FS_IRQHandler PUBWEAK DMAMUX1_OVR_IRQHandler PUBWEAK HRTIM1_Master_IRQHandler PUBWEAK HRTIM1_TIMA_IRQHandler PUBWEAK HRTIM1_TIMB_IRQHandler PUBWEAK HRTIM1_TIMC_IRQHandler PUBWEAK HRTIM1_TIMD_IRQHandler PUBWEAK HRTIM1_TIME_IRQHandler PUBWEAK HRTIM1_FLT_IRQHandler PUBWEAK DFSDM1_FLT0_IRQHandler PUBWEAK DFSDM1_FLT1_IRQHandler PUBWEAK DFSDM1_FLT2_IRQHandler PUBWEAK DFSDM1_FLT3_IRQHandler PUBWEAK SAI3_IRQHandler PUBWEAK SWPMI1_IRQHandler PUBWEAK TIM15_IRQHandler PUBWEAK TIM16_IRQHandler PUBWEAK TIM17_IRQHandler PUBWEAK MDIOS_WKUP_IRQHandler PUBWEAK MDIOS_IRQHandler PUBWEAK JPEG_IRQHandler PUBWEAK MDMA_IRQHandler PUBWEAK SDMMC2_IRQHandler PUBWEAK HSEM1_IRQHandler PUBWEAK ADC3_IRQHandler PUBWEAK DMAMUX2_OVR_IRQHandler PUBWEAK BDMA_Channel0_IRQHandler PUBWEAK BDMA_Channel1_IRQHandler PUBWEAK BDMA_Channel2_IRQHandler PUBWEAK BDMA_Channel3_IRQHandler PUBWEAK BDMA_Channel4_IRQHandler PUBWEAK BDMA_Channel5_IRQHandler PUBWEAK BDMA_Channel6_IRQHandler PUBWEAK BDMA_Channel7_IRQHandler PUBWEAK COMP1_IRQHandler PUBWEAK LPTIM2_IRQHandler PUBWEAK LPTIM3_IRQHandler PUBWEAK LPTIM4_IRQHandler PUBWEAK LPTIM5_IRQHandler PUBWEAK LPUART1_IRQHandler PUBWEAK CRS_IRQHandler PUBWEAK SAI4_IRQHandler PUBWEAK WAKEUP_PIN_IRQHandler PUBWEAK Reserved42_IRQHandler PUBWEAK Reserved64_IRQHandler PUBWEAK Reserved65_IRQHandler PUBWEAK Reserved66_IRQHandler PUBWEAK Reserved67_IRQHandler PUBWEAK Reserved79_IRQHandler PUBWEAK Reserved124_IRQHandler PUBWEAK Reserved123_IRQHandler PUBWEAK Reserved126_IRQHandler PUBWEAK Reserved143_IRQHandler PUBWEAK Reserved145_IRQHandler PUBWEAK Reserved147_IRQHandler PUBWEAK Reserved148_IRQHandler Default_Handler WWDG_IRQHandler PVD_AVD_IRQHandler TAMP_STAMP_IRQHandler RTC_WKUP_IRQHandler FLASH_IRQHandler RCC_IRQHandler EXTI0_IRQHandler EXTI1_IRQHandler EXTI2_IRQHandler EXTI3_IRQHandler EXTI4_IRQHandler DMA1_Stream0_IRQHandler DMA1_Stream1_IRQHandler DMA1_Stream2_IRQHandler DMA1_Stream3_IRQHandler DMA1_Stream4_IRQHandler DMA1_Stream5_IRQHandler DMA1_Stream6_IRQHandler ADC_IRQHandler FDCAN1_IT0_IRQHandler FDCAN2_IT0_IRQHandler FDCAN1_IT1_IRQHandler FDCAN2_IT1_IRQHandler EXTI9_5_IRQHandler TIM1_BRK_IRQHandler TIM1_UP_IRQHandler TIM1_TRG_COM_IRQHandler TIM1_CC_IRQHandler TIM2_IRQHandler TIM3_IRQHandler TIM4_IRQHandler I2C1_EV_IRQHandler I2C1_ER_IRQHandler I2C2_EV_IRQHandler I2C2_ER_IRQHandler SPI1_IRQHandler SPI2_IRQHandler USART1_IRQHandler USART2_IRQHandler USART3_IRQHandler EXTI15_10_IRQHandler RTC_Alarm_IRQHandler TIM8_BRK_TIM12_IRQHandler TIM8_UP_TIM13_IRQHandler TIM8_TRG_COM_TIM14_IRQHandler TIM8_CC_IRQHandler DMA1_Stream7_IRQHandler FMC_IRQHandler SDMMC1_IRQHandler TIM5_IRQHandler SPI3_IRQHandler UART4_IRQHandler UART5_IRQHandler TIM6_DAC_IRQHandler TIM7_IRQHandler DMA2_Stream0_IRQHandler DMA2_Stream1_IRQHandler DMA2_Stream2_IRQHandler DMA2_Stream3_IRQHandler DMA2_Stream4_IRQHandler ETH_IRQHandler ETH_WKUP_IRQHandler FDCAN_CAL_IRQHandler DMA2_Stream5_IRQHandler DMA2_Stream6_IRQHandler DMA2_Stream7_IRQHandler USART6_IRQHandler I2C3_EV_IRQHandler I2C3_ER_IRQHandler OTG_HS_EP1_OUT_IRQHandler OTG_HS_EP1_IN_IRQHandler OTG_HS_WKUP_IRQHandler OTG_HS_IRQHandler DCMI_IRQHandler RNG_IRQHandler FPU_IRQHandler UART7_IRQHandler UART8_IRQHandler SPI4_IRQHandler SPI5_IRQHandler SPI6_IRQHandler SAI1_IRQHandler LTDC_IRQHandler LTDC_ER_IRQHandler DMA2D_IRQHandler SAI2_IRQHandler QUADSPI_IRQHandler LPTIM1_IRQHandler CEC_IRQHandler I2C4_EV_IRQHandler I2C4_ER_IRQHandler SPDIF_RX_IRQHandler OTG_FS_EP1_OUT_IRQHandler OTG_FS_EP1_IN_IRQHandler OTG_FS_WKUP_IRQHandler OTG_FS_IRQHandler DMAMUX1_OVR_IRQHandler HRTIM1_Master_IRQHandler HRTIM1_TIMA_IRQHandler HRTIM1_TIMB_IRQHandler HRTIM1_TIMC_IRQHandler HRTIM1_TIMD_IRQHandler HRTIM1_TIME_IRQHandler HRTIM1_FLT_IRQHandler DFSDM1_FLT0_IRQHandler DFSDM1_FLT1_IRQHandler DFSDM1_FLT2_IRQHandler DFSDM1_FLT3_IRQHandler SAI3_IRQHandler SWPMI1_IRQHandler TIM15_IRQHandler TIM16_IRQHandler TIM17_IRQHandler MDIOS_WKUP_IRQHandler MDIOS_IRQHandler JPEG_IRQHandler MDMA_IRQHandler SDMMC2_IRQHandler HSEM1_IRQHandler ADC3_IRQHandler DMAMUX2_OVR_IRQHandler BDMA_Channel0_IRQHandler BDMA_Channel1_IRQHandler BDMA_Channel2_IRQHandler BDMA_Channel3_IRQHandler BDMA_Channel4_IRQHandler BDMA_Channel5_IRQHandler BDMA_Channel6_IRQHandler BDMA_Channel7_IRQHandler COMP1_IRQHandler LPTIM2_IRQHandler LPTIM3_IRQHandler LPTIM4_IRQHandler LPTIM5_IRQHandler LPUART1_IRQHandler CRS_IRQHandler SAI4_IRQHandler WAKEUP_PIN_IRQHandler Reserved42_IRQHandler Reserved64_IRQHandler Reserved65_IRQHandler Reserved66_IRQHandler Reserved67_IRQHandler Reserved79_IRQHandler Reserved124_IRQHandler Reserved123_IRQHandler Reserved126_IRQHandler Reserved143_IRQHandler Reserved145_IRQHandler Reserved147_IRQHandler Reserved148_IRQHandler LDR r0,=str_Undefined MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_Undefined DCB "Undefined" ALIGNROM 2 END ; end of module ================================================ FILE: 3rd_party/nucleo-h743zi/stm32h743xx.h ================================================ /** ****************************************************************************** * @file stm32h743xx.h * @author MCD Application Team * @brief CMSIS STM32H743xx Device Peripheral Access Layer Header File. * * This file contains: * - Data structures and the address mapping for all peripherals * - Peripheral's registers declarations and bits definition * - Macros to access peripheral's registers hardware * ****************************************************************************** * @attention * * Copyright (c) 2017 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /** @addtogroup CMSIS_Device * @{ */ /** @addtogroup stm32h743xx * @{ */ #ifndef STM32H743xx_H #define STM32H743xx_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** @addtogroup Peripheral_interrupt_number_definition * @{ */ /** * @brief STM32H7XX Interrupt Number Definition, according to the selected device * in @ref Library_configuration_section */ typedef enum { /****** Cortex-M Processor Exceptions Numbers *****************************************************************/ NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ HardFault_IRQn = -13, /*!< 3 Cortex-M Hard Fault Interrupt */ MemoryManagement_IRQn = -12, /*!< 4 Cortex-M Memory Management Interrupt */ BusFault_IRQn = -11, /*!< 5 Cortex-M Bus Fault Interrupt */ UsageFault_IRQn = -10, /*!< 6 Cortex-M Usage Fault Interrupt */ SVCall_IRQn = -5, /*!< 11 Cortex-M SV Call Interrupt */ DebugMonitor_IRQn = -4, /*!< 12 Cortex-M Debug Monitor Interrupt */ PendSV_IRQn = -2, /*!< 14 Cortex-M Pend SV Interrupt */ SysTick_IRQn = -1, /*!< 15 Cortex-M System Tick Interrupt */ /****** STM32 specific Interrupt Numbers **********************************************************************/ WWDG_IRQn = 0, /*!< Window WatchDog Interrupt ( wwdg1_it, wwdg2_it) */ PVD_AVD_IRQn = 1, /*!< PVD/AVD through EXTI Line detection Interrupt */ TAMP_STAMP_IRQn = 2, /*!< Tamper and TimeStamp interrupts through the EXTI line */ RTC_WKUP_IRQn = 3, /*!< RTC Wakeup interrupt through the EXTI line */ FLASH_IRQn = 4, /*!< FLASH global Interrupt */ RCC_IRQn = 5, /*!< RCC global Interrupt */ EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */ EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */ EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */ EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */ EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */ DMA1_Stream0_IRQn = 11, /*!< DMA1 Stream 0 global Interrupt */ DMA1_Stream1_IRQn = 12, /*!< DMA1 Stream 1 global Interrupt */ DMA1_Stream2_IRQn = 13, /*!< DMA1 Stream 2 global Interrupt */ DMA1_Stream3_IRQn = 14, /*!< DMA1 Stream 3 global Interrupt */ DMA1_Stream4_IRQn = 15, /*!< DMA1 Stream 4 global Interrupt */ DMA1_Stream5_IRQn = 16, /*!< DMA1 Stream 5 global Interrupt */ DMA1_Stream6_IRQn = 17, /*!< DMA1 Stream 6 global Interrupt */ ADC_IRQn = 18, /*!< ADC1 and ADC2 global Interrupts */ FDCAN1_IT0_IRQn = 19, /*!< FDCAN1 Interrupt line 0 */ FDCAN2_IT0_IRQn = 20, /*!< FDCAN2 Interrupt line 0 */ FDCAN1_IT1_IRQn = 21, /*!< FDCAN1 Interrupt line 1 */ FDCAN2_IT1_IRQn = 22, /*!< FDCAN2 Interrupt line 1 */ EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ USART1_IRQn = 37, /*!< USART1 global Interrupt */ USART2_IRQn = 38, /*!< USART2 global Interrupt */ USART3_IRQn = 39, /*!< USART3 global Interrupt */ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ RTC_Alarm_IRQn = 41, /*!< RTC Alarm (A and B) through EXTI Line Interrupt */ TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global interrupt */ TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global interrupt */ TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */ TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */ DMA1_Stream7_IRQn = 47, /*!< DMA1 Stream7 Interrupt */ FMC_IRQn = 48, /*!< FMC global Interrupt */ SDMMC1_IRQn = 49, /*!< SDMMC1 global Interrupt */ TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ UART4_IRQn = 52, /*!< UART4 global Interrupt */ UART5_IRQn = 53, /*!< UART5 global Interrupt */ TIM6_DAC_IRQn = 54, /*!< TIM6 global and DAC1&2 underrun error interrupts */ TIM7_IRQn = 55, /*!< TIM7 global interrupt */ DMA2_Stream0_IRQn = 56, /*!< DMA2 Stream 0 global Interrupt */ DMA2_Stream1_IRQn = 57, /*!< DMA2 Stream 1 global Interrupt */ DMA2_Stream2_IRQn = 58, /*!< DMA2 Stream 2 global Interrupt */ DMA2_Stream3_IRQn = 59, /*!< DMA2 Stream 3 global Interrupt */ DMA2_Stream4_IRQn = 60, /*!< DMA2 Stream 4 global Interrupt */ ETH_IRQn = 61, /*!< Ethernet global Interrupt */ ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */ FDCAN_CAL_IRQn = 63, /*!< FDCAN Calibration unit Interrupt */ DMA2_Stream5_IRQn = 68, /*!< DMA2 Stream 5 global interrupt */ DMA2_Stream6_IRQn = 69, /*!< DMA2 Stream 6 global interrupt */ DMA2_Stream7_IRQn = 70, /*!< DMA2 Stream 7 global interrupt */ USART6_IRQn = 71, /*!< USART6 global interrupt */ I2C3_EV_IRQn = 72, /*!< I2C3 event interrupt */ I2C3_ER_IRQn = 73, /*!< I2C3 error interrupt */ OTG_HS_EP1_OUT_IRQn = 74, /*!< USB OTG HS End Point 1 Out global interrupt */ OTG_HS_EP1_IN_IRQn = 75, /*!< USB OTG HS End Point 1 In global interrupt */ OTG_HS_WKUP_IRQn = 76, /*!< USB OTG HS Wakeup through EXTI interrupt */ OTG_HS_IRQn = 77, /*!< USB OTG HS global interrupt */ DCMI_IRQn = 78, /*!< DCMI global interrupt */ RNG_IRQn = 80, /*!< RNG global interrupt */ FPU_IRQn = 81, /*!< FPU global interrupt */ UART7_IRQn = 82, /*!< UART7 global interrupt */ UART8_IRQn = 83, /*!< UART8 global interrupt */ SPI4_IRQn = 84, /*!< SPI4 global Interrupt */ SPI5_IRQn = 85, /*!< SPI5 global Interrupt */ SPI6_IRQn = 86, /*!< SPI6 global Interrupt */ SAI1_IRQn = 87, /*!< SAI1 global Interrupt */ LTDC_IRQn = 88, /*!< LTDC global Interrupt */ LTDC_ER_IRQn = 89, /*!< LTDC Error global Interrupt */ DMA2D_IRQn = 90, /*!< DMA2D global Interrupt */ SAI2_IRQn = 91, /*!< SAI2 global Interrupt */ QUADSPI_IRQn = 92, /*!< Quad SPI global interrupt */ LPTIM1_IRQn = 93, /*!< LP TIM1 interrupt */ CEC_IRQn = 94, /*!< HDMI-CEC global Interrupt */ I2C4_EV_IRQn = 95, /*!< I2C4 Event Interrupt */ I2C4_ER_IRQn = 96, /*!< I2C4 Error Interrupt */ SPDIF_RX_IRQn = 97, /*!< SPDIF-RX global Interrupt */ OTG_FS_EP1_OUT_IRQn = 98, /*!< USB OTG HS2 global interrupt */ OTG_FS_EP1_IN_IRQn = 99, /*!< USB OTG HS2 End Point 1 Out global interrupt */ OTG_FS_WKUP_IRQn = 100, /*!< USB OTG HS2 End Point 1 In global interrupt */ OTG_FS_IRQn = 101, /*!< USB OTG HS2 Wakeup through EXTI interrupt */ DMAMUX1_OVR_IRQn = 102, /*! /** @addtogroup Peripheral_registers_structures * @{ */ /** * @brief Analog to Digital Converter */ typedef struct { __IO uint32_t ISR; /*!< ADC Interrupt and Status Register, Address offset: 0x00 */ __IO uint32_t IER; /*!< ADC Interrupt Enable Register, Address offset: 0x04 */ __IO uint32_t CR; /*!< ADC control register, Address offset: 0x08 */ __IO uint32_t CFGR; /*!< ADC Configuration register, Address offset: 0x0C */ __IO uint32_t CFGR2; /*!< ADC Configuration register 2, Address offset: 0x10 */ __IO uint32_t SMPR1; /*!< ADC sample time register 1, Address offset: 0x14 */ __IO uint32_t SMPR2; /*!< ADC sample time register 2, Address offset: 0x18 */ __IO uint32_t PCSEL; /*!< ADC pre-channel selection, Address offset: 0x1C */ __IO uint32_t LTR1; /*!< ADC watchdog Lower threshold register 1, Address offset: 0x20 */ __IO uint32_t HTR1; /*!< ADC watchdog higher threshold register 1, Address offset: 0x24 */ uint32_t RESERVED1; /*!< Reserved, 0x028 */ uint32_t RESERVED2; /*!< Reserved, 0x02C */ __IO uint32_t SQR1; /*!< ADC regular sequence register 1, Address offset: 0x30 */ __IO uint32_t SQR2; /*!< ADC regular sequence register 2, Address offset: 0x34 */ __IO uint32_t SQR3; /*!< ADC regular sequence register 3, Address offset: 0x38 */ __IO uint32_t SQR4; /*!< ADC regular sequence register 4, Address offset: 0x3C */ __IO uint32_t DR; /*!< ADC regular data register, Address offset: 0x40 */ uint32_t RESERVED3; /*!< Reserved, 0x044 */ uint32_t RESERVED4; /*!< Reserved, 0x048 */ __IO uint32_t JSQR; /*!< ADC injected sequence register, Address offset: 0x4C */ uint32_t RESERVED5[4]; /*!< Reserved, 0x050 - 0x05C */ __IO uint32_t OFR1; /*!< ADC offset register 1, Address offset: 0x60 */ __IO uint32_t OFR2; /*!< ADC offset register 2, Address offset: 0x64 */ __IO uint32_t OFR3; /*!< ADC offset register 3, Address offset: 0x68 */ __IO uint32_t OFR4; /*!< ADC offset register 4, Address offset: 0x6C */ uint32_t RESERVED6[4]; /*!< Reserved, 0x070 - 0x07C */ __IO uint32_t JDR1; /*!< ADC injected data register 1, Address offset: 0x80 */ __IO uint32_t JDR2; /*!< ADC injected data register 2, Address offset: 0x84 */ __IO uint32_t JDR3; /*!< ADC injected data register 3, Address offset: 0x88 */ __IO uint32_t JDR4; /*!< ADC injected data register 4, Address offset: 0x8C */ uint32_t RESERVED7[4]; /*!< Reserved, 0x090 - 0x09C */ __IO uint32_t AWD2CR; /*!< ADC Analog Watchdog 2 Configuration Register, Address offset: 0xA0 */ __IO uint32_t AWD3CR; /*!< ADC Analog Watchdog 3 Configuration Register, Address offset: 0xA4 */ uint32_t RESERVED8; /*!< Reserved, 0x0A8 */ uint32_t RESERVED9; /*!< Reserved, 0x0AC */ __IO uint32_t LTR2; /*!< ADC watchdog Lower threshold register 2, Address offset: 0xB0 */ __IO uint32_t HTR2; /*!< ADC watchdog Higher threshold register 2, Address offset: 0xB4 */ __IO uint32_t LTR3; /*!< ADC watchdog Lower threshold register 3, Address offset: 0xB8 */ __IO uint32_t HTR3; /*!< ADC watchdog Higher threshold register 3, Address offset: 0xBC */ __IO uint32_t DIFSEL; /*!< ADC Differential Mode Selection Register, Address offset: 0xC0 */ __IO uint32_t CALFACT; /*!< ADC Calibration Factors, Address offset: 0xC4 */ __IO uint32_t CALFACT2; /*!< ADC Linearity Calibration Factors, Address offset: 0xC8 */ } ADC_TypeDef; typedef struct { __IO uint32_t CSR; /*!< ADC Common status register, Address offset: ADC1/3 base address + 0x300 */ uint32_t RESERVED; /*!< Reserved, ADC1/3 base address + 0x304 */ __IO uint32_t CCR; /*!< ADC common control register, Address offset: ADC1/3 base address + 0x308 */ __IO uint32_t CDR; /*!< ADC common regular data register for dual Address offset: ADC1/3 base address + 0x30C */ __IO uint32_t CDR2; /*!< ADC common regular data register for 32-bit dual mode Address offset: ADC1/3 base address + 0x310 */ } ADC_Common_TypeDef; /** * @brief VREFBUF */ typedef struct { __IO uint32_t CSR; /*!< VREFBUF control and status register, Address offset: 0x00 */ __IO uint32_t CCR; /*!< VREFBUF calibration and control register, Address offset: 0x04 */ } VREFBUF_TypeDef; /** * @brief FD Controller Area Network */ typedef struct { __IO uint32_t CREL; /*!< FDCAN Core Release register, Address offset: 0x000 */ __IO uint32_t ENDN; /*!< FDCAN Endian register, Address offset: 0x004 */ __IO uint32_t RESERVED1; /*!< Reserved, 0x008 */ __IO uint32_t DBTP; /*!< FDCAN Data Bit Timing & Prescaler register, Address offset: 0x00C */ __IO uint32_t TEST; /*!< FDCAN Test register, Address offset: 0x010 */ __IO uint32_t RWD; /*!< FDCAN RAM Watchdog register, Address offset: 0x014 */ __IO uint32_t CCCR; /*!< FDCAN CC Control register, Address offset: 0x018 */ __IO uint32_t NBTP; /*!< FDCAN Nominal Bit Timing & Prescaler register, Address offset: 0x01C */ __IO uint32_t TSCC; /*!< FDCAN Timestamp Counter Configuration register, Address offset: 0x020 */ __IO uint32_t TSCV; /*!< FDCAN Timestamp Counter Value register, Address offset: 0x024 */ __IO uint32_t TOCC; /*!< FDCAN Timeout Counter Configuration register, Address offset: 0x028 */ __IO uint32_t TOCV; /*!< FDCAN Timeout Counter Value register, Address offset: 0x02C */ __IO uint32_t RESERVED2[4]; /*!< Reserved, 0x030 - 0x03C */ __IO uint32_t ECR; /*!< FDCAN Error Counter register, Address offset: 0x040 */ __IO uint32_t PSR; /*!< FDCAN Protocol Status register, Address offset: 0x044 */ __IO uint32_t TDCR; /*!< FDCAN Transmitter Delay Compensation register, Address offset: 0x048 */ __IO uint32_t RESERVED3; /*!< Reserved, 0x04C */ __IO uint32_t IR; /*!< FDCAN Interrupt register, Address offset: 0x050 */ __IO uint32_t IE; /*!< FDCAN Interrupt Enable register, Address offset: 0x054 */ __IO uint32_t ILS; /*!< FDCAN Interrupt Line Select register, Address offset: 0x058 */ __IO uint32_t ILE; /*!< FDCAN Interrupt Line Enable register, Address offset: 0x05C */ __IO uint32_t RESERVED4[8]; /*!< Reserved, 0x060 - 0x07C */ __IO uint32_t GFC; /*!< FDCAN Global Filter Configuration register, Address offset: 0x080 */ __IO uint32_t SIDFC; /*!< FDCAN Standard ID Filter Configuration register, Address offset: 0x084 */ __IO uint32_t XIDFC; /*!< FDCAN Extended ID Filter Configuration register, Address offset: 0x088 */ __IO uint32_t RESERVED5; /*!< Reserved, 0x08C */ __IO uint32_t XIDAM; /*!< FDCAN Extended ID AND Mask register, Address offset: 0x090 */ __IO uint32_t HPMS; /*!< FDCAN High Priority Message Status register, Address offset: 0x094 */ __IO uint32_t NDAT1; /*!< FDCAN New Data 1 register, Address offset: 0x098 */ __IO uint32_t NDAT2; /*!< FDCAN New Data 2 register, Address offset: 0x09C */ __IO uint32_t RXF0C; /*!< FDCAN Rx FIFO 0 Configuration register, Address offset: 0x0A0 */ __IO uint32_t RXF0S; /*!< FDCAN Rx FIFO 0 Status register, Address offset: 0x0A4 */ __IO uint32_t RXF0A; /*!< FDCAN Rx FIFO 0 Acknowledge register, Address offset: 0x0A8 */ __IO uint32_t RXBC; /*!< FDCAN Rx Buffer Configuration register, Address offset: 0x0AC */ __IO uint32_t RXF1C; /*!< FDCAN Rx FIFO 1 Configuration register, Address offset: 0x0B0 */ __IO uint32_t RXF1S; /*!< FDCAN Rx FIFO 1 Status register, Address offset: 0x0B4 */ __IO uint32_t RXF1A; /*!< FDCAN Rx FIFO 1 Acknowledge register, Address offset: 0x0B8 */ __IO uint32_t RXESC; /*!< FDCAN Rx Buffer/FIFO Element Size Configuration register, Address offset: 0x0BC */ __IO uint32_t TXBC; /*!< FDCAN Tx Buffer Configuration register, Address offset: 0x0C0 */ __IO uint32_t TXFQS; /*!< FDCAN Tx FIFO/Queue Status register, Address offset: 0x0C4 */ __IO uint32_t TXESC; /*!< FDCAN Tx Buffer Element Size Configuration register, Address offset: 0x0C8 */ __IO uint32_t TXBRP; /*!< FDCAN Tx Buffer Request Pending register, Address offset: 0x0CC */ __IO uint32_t TXBAR; /*!< FDCAN Tx Buffer Add Request register, Address offset: 0x0D0 */ __IO uint32_t TXBCR; /*!< FDCAN Tx Buffer Cancellation Request register, Address offset: 0x0D4 */ __IO uint32_t TXBTO; /*!< FDCAN Tx Buffer Transmission Occurred register, Address offset: 0x0D8 */ __IO uint32_t TXBCF; /*!< FDCAN Tx Buffer Cancellation Finished register, Address offset: 0x0DC */ __IO uint32_t TXBTIE; /*!< FDCAN Tx Buffer Transmission Interrupt Enable register, Address offset: 0x0E0 */ __IO uint32_t TXBCIE; /*!< FDCAN Tx Buffer Cancellation Finished Interrupt Enable register, Address offset: 0x0E4 */ __IO uint32_t RESERVED6[2]; /*!< Reserved, 0x0E8 - 0x0EC */ __IO uint32_t TXEFC; /*!< FDCAN Tx Event FIFO Configuration register, Address offset: 0x0F0 */ __IO uint32_t TXEFS; /*!< FDCAN Tx Event FIFO Status register, Address offset: 0x0F4 */ __IO uint32_t TXEFA; /*!< FDCAN Tx Event FIFO Acknowledge register, Address offset: 0x0F8 */ __IO uint32_t RESERVED7; /*!< Reserved, 0x0FC */ } FDCAN_GlobalTypeDef; /** * @brief TTFD Controller Area Network */ typedef struct { __IO uint32_t TTTMC; /*!< TT Trigger Memory Configuration register, Address offset: 0x100 */ __IO uint32_t TTRMC; /*!< TT Reference Message Configuration register, Address offset: 0x104 */ __IO uint32_t TTOCF; /*!< TT Operation Configuration register, Address offset: 0x108 */ __IO uint32_t TTMLM; /*!< TT Matrix Limits register, Address offset: 0x10C */ __IO uint32_t TURCF; /*!< TUR Configuration register, Address offset: 0x110 */ __IO uint32_t TTOCN; /*!< TT Operation Control register, Address offset: 0x114 */ __IO uint32_t TTGTP; /*!< TT Global Time Preset register, Address offset: 0x118 */ __IO uint32_t TTTMK; /*!< TT Time Mark register, Address offset: 0x11C */ __IO uint32_t TTIR; /*!< TT Interrupt register, Address offset: 0x120 */ __IO uint32_t TTIE; /*!< TT Interrupt Enable register, Address offset: 0x124 */ __IO uint32_t TTILS; /*!< TT Interrupt Line Select register, Address offset: 0x128 */ __IO uint32_t TTOST; /*!< TT Operation Status register, Address offset: 0x12C */ __IO uint32_t TURNA; /*!< TT TUR Numerator Actual register, Address offset: 0x130 */ __IO uint32_t TTLGT; /*!< TT Local and Global Time register, Address offset: 0x134 */ __IO uint32_t TTCTC; /*!< TT Cycle Time and Count register, Address offset: 0x138 */ __IO uint32_t TTCPT; /*!< TT Capture Time register, Address offset: 0x13C */ __IO uint32_t TTCSM; /*!< TT Cycle Sync Mark register, Address offset: 0x140 */ __IO uint32_t RESERVED1[111]; /*!< Reserved, 0x144 - 0x2FC */ __IO uint32_t TTTS; /*!< TT Trigger Select register, Address offset: 0x300 */ } TTCAN_TypeDef; /** * @brief FD Controller Area Network */ typedef struct { __IO uint32_t CREL; /*!< Clock Calibration Unit Core Release register, Address offset: 0x00 */ __IO uint32_t CCFG; /*!< Calibration Configuration register, Address offset: 0x04 */ __IO uint32_t CSTAT; /*!< Calibration Status register, Address offset: 0x08 */ __IO uint32_t CWD; /*!< Calibration Watchdog register, Address offset: 0x0C */ __IO uint32_t IR; /*!< CCU Interrupt register, Address offset: 0x10 */ __IO uint32_t IE; /*!< CCU Interrupt Enable register, Address offset: 0x14 */ } FDCAN_ClockCalibrationUnit_TypeDef; /** * @brief Consumer Electronics Control */ typedef struct { __IO uint32_t CR; /*!< CEC control register, Address offset:0x00 */ __IO uint32_t CFGR; /*!< CEC configuration register, Address offset:0x04 */ __IO uint32_t TXDR; /*!< CEC Tx data register , Address offset:0x08 */ __IO uint32_t RXDR; /*!< CEC Rx Data Register, Address offset:0x0C */ __IO uint32_t ISR; /*!< CEC Interrupt and Status Register, Address offset:0x10 */ __IO uint32_t IER; /*!< CEC interrupt enable register, Address offset:0x14 */ }CEC_TypeDef; /** * @brief CRC calculation unit */ typedef struct { __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */ __IO uint32_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */ __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ uint32_t RESERVED2; /*!< Reserved, 0x0C */ __IO uint32_t INIT; /*!< Initial CRC value register, Address offset: 0x10 */ __IO uint32_t POL; /*!< CRC polynomial register, Address offset: 0x14 */ } CRC_TypeDef; /** * @brief Clock Recovery System */ typedef struct { __IO uint32_t CR; /*!< CRS ccontrol register, Address offset: 0x00 */ __IO uint32_t CFGR; /*!< CRS configuration register, Address offset: 0x04 */ __IO uint32_t ISR; /*!< CRS interrupt and status register, Address offset: 0x08 */ __IO uint32_t ICR; /*!< CRS interrupt flag clear register, Address offset: 0x0C */ } CRS_TypeDef; /** * @brief Digital to Analog Converter */ typedef struct { __IO uint32_t CR; /*!< DAC control register, Address offset: 0x00 */ __IO uint32_t SWTRIGR; /*!< DAC software trigger register, Address offset: 0x04 */ __IO uint32_t DHR12R1; /*!< DAC channel1 12-bit right-aligned data holding register, Address offset: 0x08 */ __IO uint32_t DHR12L1; /*!< DAC channel1 12-bit left aligned data holding register, Address offset: 0x0C */ __IO uint32_t DHR8R1; /*!< DAC channel1 8-bit right aligned data holding register, Address offset: 0x10 */ __IO uint32_t DHR12R2; /*!< DAC channel2 12-bit right aligned data holding register, Address offset: 0x14 */ __IO uint32_t DHR12L2; /*!< DAC channel2 12-bit left aligned data holding register, Address offset: 0x18 */ __IO uint32_t DHR8R2; /*!< DAC channel2 8-bit right-aligned data holding register, Address offset: 0x1C */ __IO uint32_t DHR12RD; /*!< Dual DAC 12-bit right-aligned data holding register, Address offset: 0x20 */ __IO uint32_t DHR12LD; /*!< DUAL DAC 12-bit left aligned data holding register, Address offset: 0x24 */ __IO uint32_t DHR8RD; /*!< DUAL DAC 8-bit right aligned data holding register, Address offset: 0x28 */ __IO uint32_t DOR1; /*!< DAC channel1 data output register, Address offset: 0x2C */ __IO uint32_t DOR2; /*!< DAC channel2 data output register, Address offset: 0x30 */ __IO uint32_t SR; /*!< DAC status register, Address offset: 0x34 */ __IO uint32_t CCR; /*!< DAC calibration control register, Address offset: 0x38 */ __IO uint32_t MCR; /*!< DAC mode control register, Address offset: 0x3C */ __IO uint32_t SHSR1; /*!< DAC Sample and Hold sample time register 1, Address offset: 0x40 */ __IO uint32_t SHSR2; /*!< DAC Sample and Hold sample time register 2, Address offset: 0x44 */ __IO uint32_t SHHR; /*!< DAC Sample and Hold hold time register, Address offset: 0x48 */ __IO uint32_t SHRR; /*!< DAC Sample and Hold refresh time register, Address offset: 0x4C */ } DAC_TypeDef; /** * @brief DFSDM module registers */ typedef struct { __IO uint32_t FLTCR1; /*!< DFSDM control register1, Address offset: 0x100 */ __IO uint32_t FLTCR2; /*!< DFSDM control register2, Address offset: 0x104 */ __IO uint32_t FLTISR; /*!< DFSDM interrupt and status register, Address offset: 0x108 */ __IO uint32_t FLTICR; /*!< DFSDM interrupt flag clear register, Address offset: 0x10C */ __IO uint32_t FLTJCHGR; /*!< DFSDM injected channel group selection register, Address offset: 0x110 */ __IO uint32_t FLTFCR; /*!< DFSDM filter control register, Address offset: 0x114 */ __IO uint32_t FLTJDATAR; /*!< DFSDM data register for injected group, Address offset: 0x118 */ __IO uint32_t FLTRDATAR; /*!< DFSDM data register for regular group, Address offset: 0x11C */ __IO uint32_t FLTAWHTR; /*!< DFSDM analog watchdog high threshold register, Address offset: 0x120 */ __IO uint32_t FLTAWLTR; /*!< DFSDM analog watchdog low threshold register, Address offset: 0x124 */ __IO uint32_t FLTAWSR; /*!< DFSDM analog watchdog status register Address offset: 0x128 */ __IO uint32_t FLTAWCFR; /*!< DFSDM analog watchdog clear flag register Address offset: 0x12C */ __IO uint32_t FLTEXMAX; /*!< DFSDM extreme detector maximum register, Address offset: 0x130 */ __IO uint32_t FLTEXMIN; /*!< DFSDM extreme detector minimum register Address offset: 0x134 */ __IO uint32_t FLTCNVTIMR; /*!< DFSDM conversion timer, Address offset: 0x138 */ } DFSDM_Filter_TypeDef; /** * @brief DFSDM channel configuration registers */ typedef struct { __IO uint32_t CHCFGR1; /*!< DFSDM channel configuration register1, Address offset: 0x00 */ __IO uint32_t CHCFGR2; /*!< DFSDM channel configuration register2, Address offset: 0x04 */ __IO uint32_t CHAWSCDR; /*!< DFSDM channel analog watchdog and short circuit detector register, Address offset: 0x08 */ __IO uint32_t CHWDATAR; /*!< DFSDM channel watchdog filter data register, Address offset: 0x0C */ __IO uint32_t CHDATINR; /*!< DFSDM channel data input register, Address offset: 0x10 */ } DFSDM_Channel_TypeDef; /** * @brief Debug MCU */ typedef struct { __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */ __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */ uint32_t RESERVED4[11]; /*!< Reserved, Address offset: 0x08 */ __IO uint32_t APB3FZ1; /*!< Debug MCU APB3FZ1 freeze register, Address offset: 0x34 */ uint32_t RESERVED5; /*!< Reserved, Address offset: 0x38 */ __IO uint32_t APB1LFZ1; /*!< Debug MCU APB1LFZ1 freeze register, Address offset: 0x3C */ uint32_t RESERVED6; /*!< Reserved, Address offset: 0x40 */ __IO uint32_t APB1HFZ1; /*!< Debug MCU APB1LFZ1 freeze register, Address offset: 0x44 */ uint32_t RESERVED7; /*!< Reserved, Address offset: 0x48 */ __IO uint32_t APB2FZ1; /*!< Debug MCU APB2FZ1 freeze register, Address offset: 0x4C */ uint32_t RESERVED8; /*!< Reserved, Address offset: 0x50 */ __IO uint32_t APB4FZ1; /*!< Debug MCU APB4FZ1 freeze register, Address offset: 0x54 */ }DBGMCU_TypeDef; /** * @brief DCMI */ typedef struct { __IO uint32_t CR; /*!< DCMI control register 1, Address offset: 0x00 */ __IO uint32_t SR; /*!< DCMI status register, Address offset: 0x04 */ __IO uint32_t RISR; /*!< DCMI raw interrupt status register, Address offset: 0x08 */ __IO uint32_t IER; /*!< DCMI interrupt enable register, Address offset: 0x0C */ __IO uint32_t MISR; /*!< DCMI masked interrupt status register, Address offset: 0x10 */ __IO uint32_t ICR; /*!< DCMI interrupt clear register, Address offset: 0x14 */ __IO uint32_t ESCR; /*!< DCMI embedded synchronization code register, Address offset: 0x18 */ __IO uint32_t ESUR; /*!< DCMI embedded synchronization unmask register, Address offset: 0x1C */ __IO uint32_t CWSTRTR; /*!< DCMI crop window start, Address offset: 0x20 */ __IO uint32_t CWSIZER; /*!< DCMI crop window size, Address offset: 0x24 */ __IO uint32_t DR; /*!< DCMI data register, Address offset: 0x28 */ } DCMI_TypeDef; /** * @brief DMA Controller */ typedef struct { __IO uint32_t CR; /*!< DMA stream x configuration register */ __IO uint32_t NDTR; /*!< DMA stream x number of data register */ __IO uint32_t PAR; /*!< DMA stream x peripheral address register */ __IO uint32_t M0AR; /*!< DMA stream x memory 0 address register */ __IO uint32_t M1AR; /*!< DMA stream x memory 1 address register */ __IO uint32_t FCR; /*!< DMA stream x FIFO control register */ } DMA_Stream_TypeDef; typedef struct { __IO uint32_t LISR; /*!< DMA low interrupt status register, Address offset: 0x00 */ __IO uint32_t HISR; /*!< DMA high interrupt status register, Address offset: 0x04 */ __IO uint32_t LIFCR; /*!< DMA low interrupt flag clear register, Address offset: 0x08 */ __IO uint32_t HIFCR; /*!< DMA high interrupt flag clear register, Address offset: 0x0C */ } DMA_TypeDef; typedef struct { __IO uint32_t CCR; /*!< DMA channel x configuration register */ __IO uint32_t CNDTR; /*!< DMA channel x number of data register */ __IO uint32_t CPAR; /*!< DMA channel x peripheral address register */ __IO uint32_t CM0AR; /*!< DMA channel x memory 0 address register */ __IO uint32_t CM1AR; /*!< DMA channel x memory 1 address register */ } BDMA_Channel_TypeDef; typedef struct { __IO uint32_t ISR; /*!< DMA interrupt status register, Address offset: 0x00 */ __IO uint32_t IFCR; /*!< DMA interrupt flag clear register, Address offset: 0x04 */ } BDMA_TypeDef; typedef struct { __IO uint32_t CCR; /*!< DMA Multiplexer Channel x Control Register */ }DMAMUX_Channel_TypeDef; typedef struct { __IO uint32_t CSR; /*!< DMA Channel Status Register */ __IO uint32_t CFR; /*!< DMA Channel Clear Flag Register */ }DMAMUX_ChannelStatus_TypeDef; typedef struct { __IO uint32_t RGCR; /*!< DMA Request Generator x Control Register */ }DMAMUX_RequestGen_TypeDef; typedef struct { __IO uint32_t RGSR; /*!< DMA Request Generator Status Register */ __IO uint32_t RGCFR; /*!< DMA Request Generator Clear Flag Register */ }DMAMUX_RequestGenStatus_TypeDef; /** * @brief MDMA Controller */ typedef struct { __IO uint32_t GISR0; /*!< MDMA Global Interrupt/Status Register 0, Address offset: 0x00 */ }MDMA_TypeDef; typedef struct { __IO uint32_t CISR; /*!< MDMA channel x interrupt/status register, Address offset: 0x40 */ __IO uint32_t CIFCR; /*!< MDMA channel x interrupt flag clear register, Address offset: 0x44 */ __IO uint32_t CESR; /*!< MDMA Channel x error status register, Address offset: 0x48 */ __IO uint32_t CCR; /*!< MDMA channel x control register, Address offset: 0x4C */ __IO uint32_t CTCR; /*!< MDMA channel x Transfer Configuration register, Address offset: 0x50 */ __IO uint32_t CBNDTR; /*!< MDMA Channel x block number of data register, Address offset: 0x54 */ __IO uint32_t CSAR; /*!< MDMA channel x source address register, Address offset: 0x58 */ __IO uint32_t CDAR; /*!< MDMA channel x destination address register, Address offset: 0x5C */ __IO uint32_t CBRUR; /*!< MDMA channel x Block Repeat address Update register, Address offset: 0x60 */ __IO uint32_t CLAR; /*!< MDMA channel x Link Address register, Address offset: 0x64 */ __IO uint32_t CTBR; /*!< MDMA channel x Trigger and Bus selection Register, Address offset: 0x68 */ uint32_t RESERVED0; /*!< Reserved, 0x6C */ __IO uint32_t CMAR; /*!< MDMA channel x Mask address register, Address offset: 0x70 */ __IO uint32_t CMDR; /*!< MDMA channel x Mask Data register, Address offset: 0x74 */ }MDMA_Channel_TypeDef; /** * @brief DMA2D Controller */ typedef struct { __IO uint32_t CR; /*!< DMA2D Control Register, Address offset: 0x00 */ __IO uint32_t ISR; /*!< DMA2D Interrupt Status Register, Address offset: 0x04 */ __IO uint32_t IFCR; /*!< DMA2D Interrupt Flag Clear Register, Address offset: 0x08 */ __IO uint32_t FGMAR; /*!< DMA2D Foreground Memory Address Register, Address offset: 0x0C */ __IO uint32_t FGOR; /*!< DMA2D Foreground Offset Register, Address offset: 0x10 */ __IO uint32_t BGMAR; /*!< DMA2D Background Memory Address Register, Address offset: 0x14 */ __IO uint32_t BGOR; /*!< DMA2D Background Offset Register, Address offset: 0x18 */ __IO uint32_t FGPFCCR; /*!< DMA2D Foreground PFC Control Register, Address offset: 0x1C */ __IO uint32_t FGCOLR; /*!< DMA2D Foreground Color Register, Address offset: 0x20 */ __IO uint32_t BGPFCCR; /*!< DMA2D Background PFC Control Register, Address offset: 0x24 */ __IO uint32_t BGCOLR; /*!< DMA2D Background Color Register, Address offset: 0x28 */ __IO uint32_t FGCMAR; /*!< DMA2D Foreground CLUT Memory Address Register, Address offset: 0x2C */ __IO uint32_t BGCMAR; /*!< DMA2D Background CLUT Memory Address Register, Address offset: 0x30 */ __IO uint32_t OPFCCR; /*!< DMA2D Output PFC Control Register, Address offset: 0x34 */ __IO uint32_t OCOLR; /*!< DMA2D Output Color Register, Address offset: 0x38 */ __IO uint32_t OMAR; /*!< DMA2D Output Memory Address Register, Address offset: 0x3C */ __IO uint32_t OOR; /*!< DMA2D Output Offset Register, Address offset: 0x40 */ __IO uint32_t NLR; /*!< DMA2D Number of Line Register, Address offset: 0x44 */ __IO uint32_t LWR; /*!< DMA2D Line Watermark Register, Address offset: 0x48 */ __IO uint32_t AMTCR; /*!< DMA2D AHB Master Timer Configuration Register, Address offset: 0x4C */ uint32_t RESERVED[236]; /*!< Reserved, 0x50-0x3FF */ __IO uint32_t FGCLUT[256]; /*!< DMA2D Foreground CLUT, Address offset:400-7FF */ __IO uint32_t BGCLUT[256]; /*!< DMA2D Background CLUT, Address offset:800-BFF */ } DMA2D_TypeDef; /** * @brief Ethernet MAC */ typedef struct { __IO uint32_t MACCR; __IO uint32_t MACECR; __IO uint32_t MACPFR; __IO uint32_t MACWTR; __IO uint32_t MACHT0R; __IO uint32_t MACHT1R; uint32_t RESERVED1[14]; __IO uint32_t MACVTR; uint32_t RESERVED2; __IO uint32_t MACVHTR; uint32_t RESERVED3; __IO uint32_t MACVIR; __IO uint32_t MACIVIR; uint32_t RESERVED4[2]; __IO uint32_t MACTFCR; uint32_t RESERVED5[7]; __IO uint32_t MACRFCR; uint32_t RESERVED6[7]; __IO uint32_t MACISR; __IO uint32_t MACIER; __IO uint32_t MACRXTXSR; uint32_t RESERVED7; __IO uint32_t MACPCSR; __IO uint32_t MACRWKPFR; uint32_t RESERVED8[2]; __IO uint32_t MACLCSR; __IO uint32_t MACLTCR; __IO uint32_t MACLETR; __IO uint32_t MAC1USTCR; uint32_t RESERVED9[12]; __IO uint32_t MACVR; __IO uint32_t MACDR; uint32_t RESERVED10; __IO uint32_t MACHWF0R; __IO uint32_t MACHWF1R; __IO uint32_t MACHWF2R; uint32_t RESERVED11[54]; __IO uint32_t MACMDIOAR; __IO uint32_t MACMDIODR; uint32_t RESERVED12[2]; __IO uint32_t MACARPAR; uint32_t RESERVED13[59]; __IO uint32_t MACA0HR; __IO uint32_t MACA0LR; __IO uint32_t MACA1HR; __IO uint32_t MACA1LR; __IO uint32_t MACA2HR; __IO uint32_t MACA2LR; __IO uint32_t MACA3HR; __IO uint32_t MACA3LR; uint32_t RESERVED14[248]; __IO uint32_t MMCCR; __IO uint32_t MMCRIR; __IO uint32_t MMCTIR; __IO uint32_t MMCRIMR; __IO uint32_t MMCTIMR; uint32_t RESERVED15[14]; __IO uint32_t MMCTSCGPR; __IO uint32_t MMCTMCGPR; uint32_t RESERVED16[5]; __IO uint32_t MMCTPCGR; uint32_t RESERVED17[10]; __IO uint32_t MMCRCRCEPR; __IO uint32_t MMCRAEPR; uint32_t RESERVED18[10]; __IO uint32_t MMCRUPGR; uint32_t RESERVED19[9]; __IO uint32_t MMCTLPIMSTR; __IO uint32_t MMCTLPITCR; __IO uint32_t MMCRLPIMSTR; __IO uint32_t MMCRLPITCR; uint32_t RESERVED20[65]; __IO uint32_t MACL3L4C0R; __IO uint32_t MACL4A0R; uint32_t RESERVED21[2]; __IO uint32_t MACL3A0R0R; __IO uint32_t MACL3A1R0R; __IO uint32_t MACL3A2R0R; __IO uint32_t MACL3A3R0R; uint32_t RESERVED22[4]; __IO uint32_t MACL3L4C1R; __IO uint32_t MACL4A1R; uint32_t RESERVED23[2]; __IO uint32_t MACL3A0R1R; __IO uint32_t MACL3A1R1R; __IO uint32_t MACL3A2R1R; __IO uint32_t MACL3A3R1R; uint32_t RESERVED24[108]; __IO uint32_t MACTSCR; __IO uint32_t MACSSIR; __IO uint32_t MACSTSR; __IO uint32_t MACSTNR; __IO uint32_t MACSTSUR; __IO uint32_t MACSTNUR; __IO uint32_t MACTSAR; uint32_t RESERVED25; __IO uint32_t MACTSSR; uint32_t RESERVED26[3]; __IO uint32_t MACTTSSNR; __IO uint32_t MACTTSSSR; uint32_t RESERVED27[2]; __IO uint32_t MACACR; uint32_t RESERVED28; __IO uint32_t MACATSNR; __IO uint32_t MACATSSR; __IO uint32_t MACTSIACR; __IO uint32_t MACTSEACR; __IO uint32_t MACTSICNR; __IO uint32_t MACTSECNR; uint32_t RESERVED29[4]; __IO uint32_t MACPPSCR; uint32_t RESERVED30[3]; __IO uint32_t MACPPSTTSR; __IO uint32_t MACPPSTTNR; __IO uint32_t MACPPSIR; __IO uint32_t MACPPSWR; uint32_t RESERVED31[12]; __IO uint32_t MACPOCR; __IO uint32_t MACSPI0R; __IO uint32_t MACSPI1R; __IO uint32_t MACSPI2R; __IO uint32_t MACLMIR; uint32_t RESERVED32[11]; __IO uint32_t MTLOMR; uint32_t RESERVED33[7]; __IO uint32_t MTLISR; uint32_t RESERVED34[55]; __IO uint32_t MTLTQOMR; __IO uint32_t MTLTQUR; __IO uint32_t MTLTQDR; uint32_t RESERVED35[8]; __IO uint32_t MTLQICSR; __IO uint32_t MTLRQOMR; __IO uint32_t MTLRQMPOCR; __IO uint32_t MTLRQDR; uint32_t RESERVED36[177]; __IO uint32_t DMAMR; __IO uint32_t DMASBMR; __IO uint32_t DMAISR; __IO uint32_t DMADSR; uint32_t RESERVED37[60]; __IO uint32_t DMACCR; __IO uint32_t DMACTCR; __IO uint32_t DMACRCR; uint32_t RESERVED38[2]; __IO uint32_t DMACTDLAR; uint32_t RESERVED39; __IO uint32_t DMACRDLAR; __IO uint32_t DMACTDTPR; uint32_t RESERVED40; __IO uint32_t DMACRDTPR; __IO uint32_t DMACTDRLR; __IO uint32_t DMACRDRLR; __IO uint32_t DMACIER; __IO uint32_t DMACRIWTR; __IO uint32_t DMACSFCSR; uint32_t RESERVED41; __IO uint32_t DMACCATDR; uint32_t RESERVED42; __IO uint32_t DMACCARDR; uint32_t RESERVED43; __IO uint32_t DMACCATBR; uint32_t RESERVED44; __IO uint32_t DMACCARBR; __IO uint32_t DMACSR; uint32_t RESERVED45[2]; __IO uint32_t DMACMFCR; }ETH_TypeDef; /** * @brief External Interrupt/Event Controller */ typedef struct { __IO uint32_t RTSR1; /*!< EXTI Rising trigger selection register, Address offset: 0x00 */ __IO uint32_t FTSR1; /*!< EXTI Falling trigger selection register, Address offset: 0x04 */ __IO uint32_t SWIER1; /*!< EXTI Software interrupt event register, Address offset: 0x08 */ __IO uint32_t D3PMR1; /*!< EXTI D3 Pending mask register, (same register as to SRDPMR1) Address offset: 0x0C */ __IO uint32_t D3PCR1L; /*!< EXTI D3 Pending clear selection register low, (same register as to SRDPCR1L) Address offset: 0x10 */ __IO uint32_t D3PCR1H; /*!< EXTI D3 Pending clear selection register High, (same register as to SRDPCR1H) Address offset: 0x14 */ uint32_t RESERVED1[2]; /*!< Reserved, 0x18 to 0x1C */ __IO uint32_t RTSR2; /*!< EXTI Rising trigger selection register, Address offset: 0x20 */ __IO uint32_t FTSR2; /*!< EXTI Falling trigger selection register, Address offset: 0x24 */ __IO uint32_t SWIER2; /*!< EXTI Software interrupt event register, Address offset: 0x28 */ __IO uint32_t D3PMR2; /*!< EXTI D3 Pending mask register, (same register as to SRDPMR2) Address offset: 0x2C */ __IO uint32_t D3PCR2L; /*!< EXTI D3 Pending clear selection register low, (same register as to SRDPCR2L) Address offset: 0x30 */ __IO uint32_t D3PCR2H; /*!< EXTI D3 Pending clear selection register High, (same register as to SRDPCR2H) Address offset: 0x34 */ uint32_t RESERVED2[2]; /*!< Reserved, 0x38 to 0x3C */ __IO uint32_t RTSR3; /*!< EXTI Rising trigger selection register, Address offset: 0x40 */ __IO uint32_t FTSR3; /*!< EXTI Falling trigger selection register, Address offset: 0x44 */ __IO uint32_t SWIER3; /*!< EXTI Software interrupt event register, Address offset: 0x48 */ __IO uint32_t D3PMR3; /*!< EXTI D3 Pending mask register, (same register as to SRDPMR3) Address offset: 0x4C */ __IO uint32_t D3PCR3L; /*!< EXTI D3 Pending clear selection register low, (same register as to SRDPCR3L) Address offset: 0x50 */ __IO uint32_t D3PCR3H; /*!< EXTI D3 Pending clear selection register High, (same register as to SRDPCR3H) Address offset: 0x54 */ uint32_t RESERVED3[10]; /*!< Reserved, 0x58 to 0x7C */ __IO uint32_t IMR1; /*!< EXTI Interrupt mask register, Address offset: 0x80 */ __IO uint32_t EMR1; /*!< EXTI Event mask register, Address offset: 0x84 */ __IO uint32_t PR1; /*!< EXTI Pending register, Address offset: 0x88 */ uint32_t RESERVED4; /*!< Reserved, 0x8C */ __IO uint32_t IMR2; /*!< EXTI Interrupt mask register, Address offset: 0x90 */ __IO uint32_t EMR2; /*!< EXTI Event mask register, Address offset: 0x94 */ __IO uint32_t PR2; /*!< EXTI Pending register, Address offset: 0x98 */ uint32_t RESERVED5; /*!< Reserved, 0x9C */ __IO uint32_t IMR3; /*!< EXTI Interrupt mask register, Address offset: 0xA0 */ __IO uint32_t EMR3; /*!< EXTI Event mask register, Address offset: 0xA4 */ __IO uint32_t PR3; /*!< EXTI Pending register, Address offset: 0xA8 */ }EXTI_TypeDef; /** * @brief This structure registers corresponds to EXTI_Typdef CPU1/CPU2 registers subset (IMRx, EMRx and PRx), allowing to define EXTI_D1/EXTI_D2 * with rapid/common access to these IMRx, EMRx, PRx registers for CPU1 and CPU2. * Note that EXTI_D1 and EXTI_D2 bases addresses are calculated to point to CPUx first register: * IMR1 in case of EXTI_D1 that is addressing CPU1 (Cortex-M7) * C2IMR1 in case of EXTI_D2 that is addressing CPU2 (Cortex-M4) * Note: EXTI_D2 and corresponding C2IMRx, C2EMRx and C2PRx registers are available for Dual Core devices only */ typedef struct { __IO uint32_t IMR1; /*!< EXTI Interrupt mask register, Address offset: 0x00 */ __IO uint32_t EMR1; /*!< EXTI Event mask register, Address offset: 0x04 */ __IO uint32_t PR1; /*!< EXTI Pending register, Address offset: 0x08 */ uint32_t RESERVED1; /*!< Reserved, 0x0C */ __IO uint32_t IMR2; /*!< EXTI Interrupt mask register, Address offset: 0x10 */ __IO uint32_t EMR2; /*!< EXTI Event mask register, Address offset: 0x14 */ __IO uint32_t PR2; /*!< EXTI Pending register, Address offset: 0x18 */ uint32_t RESERVED2; /*!< Reserved, 0x1C */ __IO uint32_t IMR3; /*!< EXTI Interrupt mask register, Address offset: 0x20 */ __IO uint32_t EMR3; /*!< EXTI Event mask register, Address offset: 0x24 */ __IO uint32_t PR3; /*!< EXTI Pending register, Address offset: 0x28 */ }EXTI_Core_TypeDef; /** * @brief FLASH Registers */ typedef struct { __IO uint32_t ACR; /*!< FLASH access control register, Address offset: 0x00 */ __IO uint32_t KEYR1; /*!< Flash Key Register for bank1, Address offset: 0x04 */ __IO uint32_t OPTKEYR; /*!< Flash Option Key Register, Address offset: 0x08 */ __IO uint32_t CR1; /*!< Flash Control Register for bank1, Address offset: 0x0C */ __IO uint32_t SR1; /*!< Flash Status Register for bank1, Address offset: 0x10 */ __IO uint32_t CCR1; /*!< Flash Control Register for bank1, Address offset: 0x14 */ __IO uint32_t OPTCR; /*!< Flash Option Control Register, Address offset: 0x18 */ __IO uint32_t OPTSR_CUR; /*!< Flash Option Status Current Register, Address offset: 0x1C */ __IO uint32_t OPTSR_PRG; /*!< Flash Option Status to Program Register, Address offset: 0x20 */ __IO uint32_t OPTCCR; /*!< Flash Option Clear Control Register, Address offset: 0x24 */ __IO uint32_t PRAR_CUR1; /*!< Flash Current Protection Address Register for bank1, Address offset: 0x28 */ __IO uint32_t PRAR_PRG1; /*!< Flash Protection Address to Program Register for bank1, Address offset: 0x2C */ __IO uint32_t SCAR_CUR1; /*!< Flash Current Secure Address Register for bank1, Address offset: 0x30 */ __IO uint32_t SCAR_PRG1; /*!< Flash Secure Address to Program Register for bank1, Address offset: 0x34 */ __IO uint32_t WPSN_CUR1; /*!< Flash Current Write Protection Register on bank1, Address offset: 0x38 */ __IO uint32_t WPSN_PRG1; /*!< Flash Write Protection to Program Register on bank1, Address offset: 0x3C */ __IO uint32_t BOOT_CUR; /*!< Flash Current Boot Address for Pelican Core Register, Address offset: 0x40 */ __IO uint32_t BOOT_PRG; /*!< Flash Boot Address to Program for Pelican Core Register, Address offset: 0x44 */ uint32_t RESERVED0[2]; /*!< Reserved, 0x48 to 0x4C */ __IO uint32_t CRCCR1; /*!< Flash CRC Control register For Bank1 Register , Address offset: 0x50 */ __IO uint32_t CRCSADD1; /*!< Flash CRC Start Address Register for Bank1 , Address offset: 0x54 */ __IO uint32_t CRCEADD1; /*!< Flash CRC End Address Register for Bank1 , Address offset: 0x58 */ __IO uint32_t CRCDATA; /*!< Flash CRC Data Register for Bank1 , Address offset: 0x5C */ __IO uint32_t ECC_FA1; /*!< Flash ECC Fail Address For Bank1 Register , Address offset: 0x60 */ uint32_t RESERVED1[40]; /*!< Reserved, 0x64 to 0x100 */ __IO uint32_t KEYR2; /*!< Flash Key Register for bank2, Address offset: 0x104 */ uint32_t RESERVED2; /*!< Reserved, 0x108 */ __IO uint32_t CR2; /*!< Flash Control Register for bank2, Address offset: 0x10C */ __IO uint32_t SR2; /*!< Flash Status Register for bank2, Address offset: 0x110 */ __IO uint32_t CCR2; /*!< Flash Status Register for bank2, Address offset: 0x114 */ uint32_t RESERVED3[4]; /*!< Reserved, 0x118 to 0x124 */ __IO uint32_t PRAR_CUR2; /*!< Flash Current Protection Address Register for bank2, Address offset: 0x128 */ __IO uint32_t PRAR_PRG2; /*!< Flash Protection Address to Program Register for bank2, Address offset: 0x12C */ __IO uint32_t SCAR_CUR2; /*!< Flash Current Secure Address Register for bank2, Address offset: 0x130 */ __IO uint32_t SCAR_PRG2; /*!< Flash Secure Address Register for bank2, Address offset: 0x134 */ __IO uint32_t WPSN_CUR2; /*!< Flash Current Write Protection Register on bank2, Address offset: 0x138 */ __IO uint32_t WPSN_PRG2; /*!< Flash Write Protection to Program Register on bank2, Address offset: 0x13C */ uint32_t RESERVED4[4]; /*!< Reserved, 0x140 to 0x14C */ __IO uint32_t CRCCR2; /*!< Flash CRC Control register For Bank2 Register , Address offset: 0x150 */ __IO uint32_t CRCSADD2; /*!< Flash CRC Start Address Register for Bank2 , Address offset: 0x154 */ __IO uint32_t CRCEADD2; /*!< Flash CRC End Address Register for Bank2 , Address offset: 0x158 */ __IO uint32_t CRCDATA2; /*!< Flash CRC Data Register for Bank2 , Address offset: 0x15C */ __IO uint32_t ECC_FA2; /*!< Flash ECC Fail Address For Bank2 Register , Address offset: 0x160 */ } FLASH_TypeDef; /** * @brief Flexible Memory Controller */ typedef struct { __IO uint32_t BTCR[8]; /*!< NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR), Address offset: 0x00-1C */ } FMC_Bank1_TypeDef; /** * @brief Flexible Memory Controller Bank1E */ typedef struct { __IO uint32_t BWTR[7]; /*!< NOR/PSRAM write timing registers, Address offset: 0x104-0x11C */ } FMC_Bank1E_TypeDef; /** * @brief Flexible Memory Controller Bank2 */ typedef struct { __IO uint32_t PCR2; /*!< NAND Flash control register 2, Address offset: 0x60 */ __IO uint32_t SR2; /*!< NAND Flash FIFO status and interrupt register 2, Address offset: 0x64 */ __IO uint32_t PMEM2; /*!< NAND Flash Common memory space timing register 2, Address offset: 0x68 */ __IO uint32_t PATT2; /*!< NAND Flash Attribute memory space timing register 2, Address offset: 0x6C */ uint32_t RESERVED0; /*!< Reserved, 0x70 */ __IO uint32_t ECCR2; /*!< NAND Flash ECC result registers 2, Address offset: 0x74 */ } FMC_Bank2_TypeDef; /** * @brief Flexible Memory Controller Bank3 */ typedef struct { __IO uint32_t PCR; /*!< NAND Flash control register 3, Address offset: 0x80 */ __IO uint32_t SR; /*!< NAND Flash FIFO status and interrupt register 3, Address offset: 0x84 */ __IO uint32_t PMEM; /*!< NAND Flash Common memory space timing register 3, Address offset: 0x88 */ __IO uint32_t PATT; /*!< NAND Flash Attribute memory space timing register 3, Address offset: 0x8C */ uint32_t RESERVED; /*!< Reserved, 0x90 */ __IO uint32_t ECCR; /*!< NAND Flash ECC result registers 3, Address offset: 0x94 */ } FMC_Bank3_TypeDef; /** * @brief Flexible Memory Controller Bank5 and 6 */ typedef struct { __IO uint32_t SDCR[2]; /*!< SDRAM Control registers , Address offset: 0x140-0x144 */ __IO uint32_t SDTR[2]; /*!< SDRAM Timing registers , Address offset: 0x148-0x14C */ __IO uint32_t SDCMR; /*!< SDRAM Command Mode register, Address offset: 0x150 */ __IO uint32_t SDRTR; /*!< SDRAM Refresh Timer register, Address offset: 0x154 */ __IO uint32_t SDSR; /*!< SDRAM Status register, Address offset: 0x158 */ } FMC_Bank5_6_TypeDef; /** * @brief General Purpose I/O */ typedef struct { __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ __IO uint32_t BSRR; /*!< GPIO port bit set/reset, Address offset: 0x18 */ __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ } GPIO_TypeDef; /** * @brief Operational Amplifier (OPAMP) */ typedef struct { __IO uint32_t CSR; /*!< OPAMP control/status register, Address offset: 0x00 */ __IO uint32_t OTR; /*!< OPAMP offset trimming register for normal mode, Address offset: 0x04 */ __IO uint32_t HSOTR; /*!< OPAMP offset trimming register for high speed mode, Address offset: 0x08 */ } OPAMP_TypeDef; /** * @brief System configuration controller */ typedef struct { uint32_t RESERVED1; /*!< Reserved, Address offset: 0x00 */ __IO uint32_t PMCR; /*!< SYSCFG peripheral mode configuration register, Address offset: 0x04 */ __IO uint32_t EXTICR[4]; /*!< SYSCFG external interrupt configuration registers, Address offset: 0x08-0x14 */ __IO uint32_t CFGR; /*!< SYSCFG configuration registers, Address offset: 0x18 */ uint32_t RESERVED2; /*!< Reserved, Address offset: 0x1C */ __IO uint32_t CCCSR; /*!< SYSCFG compensation cell control/status register, Address offset: 0x20 */ __IO uint32_t CCVR; /*!< SYSCFG compensation cell value register, Address offset: 0x24 */ __IO uint32_t CCCR; /*!< SYSCFG compensation cell code register, Address offset: 0x28 */ __IO uint32_t PWRCR; /*!< PWR control register, Address offset: 0x2C */ uint32_t RESERVED3[61]; /*!< Reserved, 0x30-0x120 */ __IO uint32_t PKGR; /*!< SYSCFG package register, Address offset: 0x124 */ uint32_t RESERVED4[118]; /*!< Reserved, 0x128-0x2FC */ __IO uint32_t UR0; /*!< SYSCFG user register 0, Address offset: 0x300 */ __IO uint32_t UR1; /*!< SYSCFG user register 1, Address offset: 0x304 */ __IO uint32_t UR2; /*!< SYSCFG user register 2, Address offset: 0x308 */ __IO uint32_t UR3; /*!< SYSCFG user register 3, Address offset: 0x30C */ __IO uint32_t UR4; /*!< SYSCFG user register 4, Address offset: 0x310 */ __IO uint32_t UR5; /*!< SYSCFG user register 5, Address offset: 0x314 */ __IO uint32_t UR6; /*!< SYSCFG user register 6, Address offset: 0x318 */ __IO uint32_t UR7; /*!< SYSCFG user register 7, Address offset: 0x31C */ __IO uint32_t UR8; /*!< SYSCFG user register 8, Address offset: 0x320 */ __IO uint32_t UR9; /*!< SYSCFG user register 9, Address offset: 0x324 */ __IO uint32_t UR10; /*!< SYSCFG user register 10, Address offset: 0x328 */ __IO uint32_t UR11; /*!< SYSCFG user register 11, Address offset: 0x32C */ __IO uint32_t UR12; /*!< SYSCFG user register 12, Address offset: 0x330 */ __IO uint32_t UR13; /*!< SYSCFG user register 13, Address offset: 0x334 */ __IO uint32_t UR14; /*!< SYSCFG user register 14, Address offset: 0x338 */ __IO uint32_t UR15; /*!< SYSCFG user register 15, Address offset: 0x33C */ __IO uint32_t UR16; /*!< SYSCFG user register 16, Address offset: 0x340 */ __IO uint32_t UR17; /*!< SYSCFG user register 17, Address offset: 0x344 */ } SYSCFG_TypeDef; /** * @brief Inter-integrated Circuit Interface */ typedef struct { __IO uint32_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */ __IO uint32_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */ __IO uint32_t OAR1; /*!< I2C Own address 1 register, Address offset: 0x08 */ __IO uint32_t OAR2; /*!< I2C Own address 2 register, Address offset: 0x0C */ __IO uint32_t TIMINGR; /*!< I2C Timing register, Address offset: 0x10 */ __IO uint32_t TIMEOUTR; /*!< I2C Timeout register, Address offset: 0x14 */ __IO uint32_t ISR; /*!< I2C Interrupt and status register, Address offset: 0x18 */ __IO uint32_t ICR; /*!< I2C Interrupt clear register, Address offset: 0x1C */ __IO uint32_t PECR; /*!< I2C PEC register, Address offset: 0x20 */ __IO uint32_t RXDR; /*!< I2C Receive data register, Address offset: 0x24 */ __IO uint32_t TXDR; /*!< I2C Transmit data register, Address offset: 0x28 */ } I2C_TypeDef; /** * @brief Independent WATCHDOG */ typedef struct { __IO uint32_t KR; /*!< IWDG Key register, Address offset: 0x00 */ __IO uint32_t PR; /*!< IWDG Prescaler register, Address offset: 0x04 */ __IO uint32_t RLR; /*!< IWDG Reload register, Address offset: 0x08 */ __IO uint32_t SR; /*!< IWDG Status register, Address offset: 0x0C */ __IO uint32_t WINR; /*!< IWDG Window register, Address offset: 0x10 */ } IWDG_TypeDef; /** * @brief JPEG Codec */ typedef struct { __IO uint32_t CONFR0; /*!< JPEG Codec Control Register (JPEG_CONFR0), Address offset: 00h */ __IO uint32_t CONFR1; /*!< JPEG Codec Control Register (JPEG_CONFR1), Address offset: 04h */ __IO uint32_t CONFR2; /*!< JPEG Codec Control Register (JPEG_CONFR2), Address offset: 08h */ __IO uint32_t CONFR3; /*!< JPEG Codec Control Register (JPEG_CONFR3), Address offset: 0Ch */ __IO uint32_t CONFR4; /*!< JPEG Codec Control Register (JPEG_CONFR4), Address offset: 10h */ __IO uint32_t CONFR5; /*!< JPEG Codec Control Register (JPEG_CONFR5), Address offset: 14h */ __IO uint32_t CONFR6; /*!< JPEG Codec Control Register (JPEG_CONFR6), Address offset: 18h */ __IO uint32_t CONFR7; /*!< JPEG Codec Control Register (JPEG_CONFR7), Address offset: 1Ch */ uint32_t Reserved20[4]; /* Reserved Address offset: 20h-2Ch */ __IO uint32_t CR; /*!< JPEG Control Register (JPEG_CR), Address offset: 30h */ __IO uint32_t SR; /*!< JPEG Status Register (JPEG_SR), Address offset: 34h */ __IO uint32_t CFR; /*!< JPEG Clear Flag Register (JPEG_CFR), Address offset: 38h */ uint32_t Reserved3c; /* Reserved Address offset: 3Ch */ __IO uint32_t DIR; /*!< JPEG Data Input Register (JPEG_DIR), Address offset: 40h */ __IO uint32_t DOR; /*!< JPEG Data Output Register (JPEG_DOR), Address offset: 44h */ uint32_t Reserved48[2]; /* Reserved Address offset: 48h-4Ch */ __IO uint32_t QMEM0[16]; /*!< JPEG quantization tables 0, Address offset: 50h-8Ch */ __IO uint32_t QMEM1[16]; /*!< JPEG quantization tables 1, Address offset: 90h-CCh */ __IO uint32_t QMEM2[16]; /*!< JPEG quantization tables 2, Address offset: D0h-10Ch */ __IO uint32_t QMEM3[16]; /*!< JPEG quantization tables 3, Address offset: 110h-14Ch */ __IO uint32_t HUFFMIN[16]; /*!< JPEG HuffMin tables, Address offset: 150h-18Ch */ __IO uint32_t HUFFBASE[32]; /*!< JPEG HuffSymb tables, Address offset: 190h-20Ch */ __IO uint32_t HUFFSYMB[84]; /*!< JPEG HUFFSYMB tables, Address offset: 210h-35Ch */ __IO uint32_t DHTMEM[103]; /*!< JPEG DHTMem tables, Address offset: 360h-4F8h */ uint32_t Reserved4FC; /* Reserved Address offset: 4FCh */ __IO uint32_t HUFFENC_AC0[88]; /*!< JPEG encodor, AC Huffman table 0, Address offset: 500h-65Ch */ __IO uint32_t HUFFENC_AC1[88]; /*!< JPEG encodor, AC Huffman table 1, Address offset: 660h-7BCh */ __IO uint32_t HUFFENC_DC0[8]; /*!< JPEG encodor, DC Huffman table 0, Address offset: 7C0h-7DCh */ __IO uint32_t HUFFENC_DC1[8]; /*!< JPEG encodor, DC Huffman table 1, Address offset: 7E0h-7FCh */ } JPEG_TypeDef; /** * @brief LCD-TFT Display Controller */ typedef struct { uint32_t RESERVED0[2]; /*!< Reserved, 0x00-0x04 */ __IO uint32_t SSCR; /*!< LTDC Synchronization Size Configuration Register, Address offset: 0x08 */ __IO uint32_t BPCR; /*!< LTDC Back Porch Configuration Register, Address offset: 0x0C */ __IO uint32_t AWCR; /*!< LTDC Active Width Configuration Register, Address offset: 0x10 */ __IO uint32_t TWCR; /*!< LTDC Total Width Configuration Register, Address offset: 0x14 */ __IO uint32_t GCR; /*!< LTDC Global Control Register, Address offset: 0x18 */ uint32_t RESERVED1[2]; /*!< Reserved, 0x1C-0x20 */ __IO uint32_t SRCR; /*!< LTDC Shadow Reload Configuration Register, Address offset: 0x24 */ uint32_t RESERVED2[1]; /*!< Reserved, 0x28 */ __IO uint32_t BCCR; /*!< LTDC Background Color Configuration Register, Address offset: 0x2C */ uint32_t RESERVED3[1]; /*!< Reserved, 0x30 */ __IO uint32_t IER; /*!< LTDC Interrupt Enable Register, Address offset: 0x34 */ __IO uint32_t ISR; /*!< LTDC Interrupt Status Register, Address offset: 0x38 */ __IO uint32_t ICR; /*!< LTDC Interrupt Clear Register, Address offset: 0x3C */ __IO uint32_t LIPCR; /*!< LTDC Line Interrupt Position Configuration Register, Address offset: 0x40 */ __IO uint32_t CPSR; /*!< LTDC Current Position Status Register, Address offset: 0x44 */ __IO uint32_t CDSR; /*!< LTDC Current Display Status Register, Address offset: 0x48 */ } LTDC_TypeDef; /** * @brief LCD-TFT Display layer x Controller */ typedef struct { __IO uint32_t CR; /*!< LTDC Layerx Control Register Address offset: 0x84 */ __IO uint32_t WHPCR; /*!< LTDC Layerx Window Horizontal Position Configuration Register Address offset: 0x88 */ __IO uint32_t WVPCR; /*!< LTDC Layerx Window Vertical Position Configuration Register Address offset: 0x8C */ __IO uint32_t CKCR; /*!< LTDC Layerx Color Keying Configuration Register Address offset: 0x90 */ __IO uint32_t PFCR; /*!< LTDC Layerx Pixel Format Configuration Register Address offset: 0x94 */ __IO uint32_t CACR; /*!< LTDC Layerx Constant Alpha Configuration Register Address offset: 0x98 */ __IO uint32_t DCCR; /*!< LTDC Layerx Default Color Configuration Register Address offset: 0x9C */ __IO uint32_t BFCR; /*!< LTDC Layerx Blending Factors Configuration Register Address offset: 0xA0 */ uint32_t RESERVED0[2]; /*!< Reserved */ __IO uint32_t CFBAR; /*!< LTDC Layerx Color Frame Buffer Address Register Address offset: 0xAC */ __IO uint32_t CFBLR; /*!< LTDC Layerx Color Frame Buffer Length Register Address offset: 0xB0 */ __IO uint32_t CFBLNR; /*!< LTDC Layerx ColorFrame Buffer Line Number Register Address offset: 0xB4 */ uint32_t RESERVED1[3]; /*!< Reserved */ __IO uint32_t CLUTWR; /*!< LTDC Layerx CLUT Write Register Address offset: 0x144 */ } LTDC_Layer_TypeDef; /** * @brief Power Control */ typedef struct { __IO uint32_t CR1; /*!< PWR power control register 1, Address offset: 0x00 */ __IO uint32_t CSR1; /*!< PWR power control status register 1, Address offset: 0x04 */ __IO uint32_t CR2; /*!< PWR power control register 2, Address offset: 0x08 */ __IO uint32_t CR3; /*!< PWR power control register 3, Address offset: 0x0C */ __IO uint32_t CPUCR; /*!< PWR CPU control register, Address offset: 0x10 */ uint32_t RESERVED0; /*!< Reserved, Address offset: 0x14 */ __IO uint32_t D3CR; /*!< PWR D3 domain control register, Address offset: 0x18 */ uint32_t RESERVED1; /*!< Reserved, Address offset: 0x1C */ __IO uint32_t WKUPCR; /*!< PWR wakeup clear register, Address offset: 0x20 */ __IO uint32_t WKUPFR; /*!< PWR wakeup flag register, Address offset: 0x24 */ __IO uint32_t WKUPEPR; /*!< PWR wakeup enable and polarity register, Address offset: 0x28 */ } PWR_TypeDef; /** * @brief Reset and Clock Control */ typedef struct { __IO uint32_t CR; /*!< RCC clock control register, Address offset: 0x00 */ __IO uint32_t HSICFGR; /*!< HSI Clock Calibration Register, Address offset: 0x04 */ __IO uint32_t CRRCR; /*!< Clock Recovery RC Register, Address offset: 0x08 */ __IO uint32_t CSICFGR; /*!< CSI Clock Calibration Register, Address offset: 0x0C */ __IO uint32_t CFGR; /*!< RCC clock configuration register, Address offset: 0x10 */ uint32_t RESERVED1; /*!< Reserved, Address offset: 0x14 */ __IO uint32_t D1CFGR; /*!< RCC Domain 1 configuration register, Address offset: 0x18 */ __IO uint32_t D2CFGR; /*!< RCC Domain 2 configuration register, Address offset: 0x1C */ __IO uint32_t D3CFGR; /*!< RCC Domain 3 configuration register, Address offset: 0x20 */ uint32_t RESERVED2; /*!< Reserved, Address offset: 0x24 */ __IO uint32_t PLLCKSELR; /*!< RCC PLLs Clock Source Selection Register, Address offset: 0x28 */ __IO uint32_t PLLCFGR; /*!< RCC PLLs Configuration Register, Address offset: 0x2C */ __IO uint32_t PLL1DIVR; /*!< RCC PLL1 Dividers Configuration Register, Address offset: 0x30 */ __IO uint32_t PLL1FRACR; /*!< RCC PLL1 Fractional Divider Configuration Register, Address offset: 0x34 */ __IO uint32_t PLL2DIVR; /*!< RCC PLL2 Dividers Configuration Register, Address offset: 0x38 */ __IO uint32_t PLL2FRACR; /*!< RCC PLL2 Fractional Divider Configuration Register, Address offset: 0x3C */ __IO uint32_t PLL3DIVR; /*!< RCC PLL3 Dividers Configuration Register, Address offset: 0x40 */ __IO uint32_t PLL3FRACR; /*!< RCC PLL3 Fractional Divider Configuration Register, Address offset: 0x44 */ uint32_t RESERVED3; /*!< Reserved, Address offset: 0x48 */ __IO uint32_t D1CCIPR; /*!< RCC Domain 1 Kernel Clock Configuration Register Address offset: 0x4C */ __IO uint32_t D2CCIP1R; /*!< RCC Domain 2 Kernel Clock Configuration Register Address offset: 0x50 */ __IO uint32_t D2CCIP2R; /*!< RCC Domain 2 Kernel Clock Configuration Register Address offset: 0x54 */ __IO uint32_t D3CCIPR; /*!< RCC Domain 3 Kernel Clock Configuration Register Address offset: 0x58 */ uint32_t RESERVED4; /*!< Reserved, Address offset: 0x5C */ __IO uint32_t CIER; /*!< RCC Clock Source Interrupt Enable Register Address offset: 0x60 */ __IO uint32_t CIFR; /*!< RCC Clock Source Interrupt Flag Register Address offset: 0x64 */ __IO uint32_t CICR; /*!< RCC Clock Source Interrupt Clear Register Address offset: 0x68 */ uint32_t RESERVED5; /*!< Reserved, Address offset: 0x6C */ __IO uint32_t BDCR; /*!< RCC Vswitch Backup Domain Control Register, Address offset: 0x70 */ __IO uint32_t CSR; /*!< RCC clock control & status register, Address offset: 0x74 */ uint32_t RESERVED6; /*!< Reserved, Address offset: 0x78 */ __IO uint32_t AHB3RSTR; /*!< RCC AHB3 peripheral reset register, Address offset: 0x7C */ __IO uint32_t AHB1RSTR; /*!< RCC AHB1 peripheral reset register, Address offset: 0x80 */ __IO uint32_t AHB2RSTR; /*!< RCC AHB2 peripheral reset register, Address offset: 0x84 */ __IO uint32_t AHB4RSTR; /*!< RCC AHB4 peripheral reset register, Address offset: 0x88 */ __IO uint32_t APB3RSTR; /*!< RCC APB3 peripheral reset register, Address offset: 0x8C */ __IO uint32_t APB1LRSTR; /*!< RCC APB1 peripheral reset Low Word register, Address offset: 0x90 */ __IO uint32_t APB1HRSTR; /*!< RCC APB1 peripheral reset High Word register, Address offset: 0x94 */ __IO uint32_t APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x98 */ __IO uint32_t APB4RSTR; /*!< RCC APB4 peripheral reset register, Address offset: 0x9C */ __IO uint32_t GCR; /*!< RCC RCC Global Control Register, Address offset: 0xA0 */ uint32_t RESERVED8; /*!< Reserved, Address offset: 0xA4 */ __IO uint32_t D3AMR; /*!< RCC Domain 3 Autonomous Mode Register, Address offset: 0xA8 */ uint32_t RESERVED11[9]; /*!< Reserved, 0xAC-0xCC Address offset: 0xAC */ __IO uint32_t RSR; /*!< RCC Reset status register, Address offset: 0xD0 */ __IO uint32_t AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0xD4 */ __IO uint32_t AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0xD8 */ __IO uint32_t AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0xDC */ __IO uint32_t AHB4ENR; /*!< RCC AHB4 peripheral clock register, Address offset: 0xE0 */ __IO uint32_t APB3ENR; /*!< RCC APB3 peripheral clock register, Address offset: 0xE4 */ __IO uint32_t APB1LENR; /*!< RCC APB1 peripheral clock Low Word register, Address offset: 0xE8 */ __IO uint32_t APB1HENR; /*!< RCC APB1 peripheral clock High Word register, Address offset: 0xEC */ __IO uint32_t APB2ENR; /*!< RCC APB2 peripheral clock register, Address offset: 0xF0 */ __IO uint32_t APB4ENR; /*!< RCC APB4 peripheral clock register, Address offset: 0xF4 */ uint32_t RESERVED12; /*!< Reserved, Address offset: 0xF8 */ __IO uint32_t AHB3LPENR; /*!< RCC AHB3 peripheral sleep clock register, Address offset: 0xFC */ __IO uint32_t AHB1LPENR; /*!< RCC AHB1 peripheral sleep clock register, Address offset: 0x100 */ __IO uint32_t AHB2LPENR; /*!< RCC AHB2 peripheral sleep clock register, Address offset: 0x104 */ __IO uint32_t AHB4LPENR; /*!< RCC AHB4 peripheral sleep clock register, Address offset: 0x108 */ __IO uint32_t APB3LPENR; /*!< RCC APB3 peripheral sleep clock register, Address offset: 0x10C */ __IO uint32_t APB1LLPENR; /*!< RCC APB1 peripheral sleep clock Low Word register, Address offset: 0x110 */ __IO uint32_t APB1HLPENR; /*!< RCC APB1 peripheral sleep clock High Word register, Address offset: 0x114 */ __IO uint32_t APB2LPENR; /*!< RCC APB2 peripheral sleep clock register, Address offset: 0x118 */ __IO uint32_t APB4LPENR; /*!< RCC APB4 peripheral sleep clock register, Address offset: 0x11C */ uint32_t RESERVED13[4]; /*!< Reserved, 0x120-0x12C Address offset: 0x120 */ } RCC_TypeDef; /** * @brief Real-Time Clock */ typedef struct { __IO uint32_t TR; /*!< RTC time register, Address offset: 0x00 */ __IO uint32_t DR; /*!< RTC date register, Address offset: 0x04 */ __IO uint32_t CR; /*!< RTC control register, Address offset: 0x08 */ __IO uint32_t ISR; /*!< RTC initialization and status register, Address offset: 0x0C */ __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ __IO uint32_t WUTR; /*!< RTC wakeup timer register, Address offset: 0x14 */ uint32_t RESERVED; /*!< Reserved, Address offset: 0x18 */ __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x1C */ __IO uint32_t ALRMBR; /*!< RTC alarm B register, Address offset: 0x20 */ __IO uint32_t WPR; /*!< RTC write protection register, Address offset: 0x24 */ __IO uint32_t SSR; /*!< RTC sub second register, Address offset: 0x28 */ __IO uint32_t SHIFTR; /*!< RTC shift control register, Address offset: 0x2C */ __IO uint32_t TSTR; /*!< RTC time stamp time register, Address offset: 0x30 */ __IO uint32_t TSDR; /*!< RTC time stamp date register, Address offset: 0x34 */ __IO uint32_t TSSSR; /*!< RTC time-stamp sub second register, Address offset: 0x38 */ __IO uint32_t CALR; /*!< RTC calibration register, Address offset: 0x3C */ __IO uint32_t TAMPCR; /*!< RTC tamper configuration register, Address offset: 0x40 */ __IO uint32_t ALRMASSR; /*!< RTC alarm A sub second register, Address offset: 0x44 */ __IO uint32_t ALRMBSSR; /*!< RTC alarm B sub second register, Address offset: 0x48 */ __IO uint32_t OR; /*!< RTC option register, Address offset: 0x4C */ __IO uint32_t BKP0R; /*!< RTC backup register 0, Address offset: 0x50 */ __IO uint32_t BKP1R; /*!< RTC backup register 1, Address offset: 0x54 */ __IO uint32_t BKP2R; /*!< RTC backup register 2, Address offset: 0x58 */ __IO uint32_t BKP3R; /*!< RTC backup register 3, Address offset: 0x5C */ __IO uint32_t BKP4R; /*!< RTC backup register 4, Address offset: 0x60 */ __IO uint32_t BKP5R; /*!< RTC backup register 5, Address offset: 0x64 */ __IO uint32_t BKP6R; /*!< RTC backup register 6, Address offset: 0x68 */ __IO uint32_t BKP7R; /*!< RTC backup register 7, Address offset: 0x6C */ __IO uint32_t BKP8R; /*!< RTC backup register 8, Address offset: 0x70 */ __IO uint32_t BKP9R; /*!< RTC backup register 9, Address offset: 0x74 */ __IO uint32_t BKP10R; /*!< RTC backup register 10, Address offset: 0x78 */ __IO uint32_t BKP11R; /*!< RTC backup register 11, Address offset: 0x7C */ __IO uint32_t BKP12R; /*!< RTC backup register 12, Address offset: 0x80 */ __IO uint32_t BKP13R; /*!< RTC backup register 13, Address offset: 0x84 */ __IO uint32_t BKP14R; /*!< RTC backup register 14, Address offset: 0x88 */ __IO uint32_t BKP15R; /*!< RTC backup register 15, Address offset: 0x8C */ __IO uint32_t BKP16R; /*!< RTC backup register 16, Address offset: 0x90 */ __IO uint32_t BKP17R; /*!< RTC backup register 17, Address offset: 0x94 */ __IO uint32_t BKP18R; /*!< RTC backup register 18, Address offset: 0x98 */ __IO uint32_t BKP19R; /*!< RTC backup register 19, Address offset: 0x9C */ __IO uint32_t BKP20R; /*!< RTC backup register 20, Address offset: 0xA0 */ __IO uint32_t BKP21R; /*!< RTC backup register 21, Address offset: 0xA4 */ __IO uint32_t BKP22R; /*!< RTC backup register 22, Address offset: 0xA8 */ __IO uint32_t BKP23R; /*!< RTC backup register 23, Address offset: 0xAC */ __IO uint32_t BKP24R; /*!< RTC backup register 24, Address offset: 0xB0 */ __IO uint32_t BKP25R; /*!< RTC backup register 25, Address offset: 0xB4 */ __IO uint32_t BKP26R; /*!< RTC backup register 26, Address offset: 0xB8 */ __IO uint32_t BKP27R; /*!< RTC backup register 27, Address offset: 0xBC */ __IO uint32_t BKP28R; /*!< RTC backup register 28, Address offset: 0xC0 */ __IO uint32_t BKP29R; /*!< RTC backup register 29, Address offset: 0xC4 */ __IO uint32_t BKP30R; /*!< RTC backup register 30, Address offset: 0xC8 */ __IO uint32_t BKP31R; /*!< RTC backup register 31, Address offset: 0xCC */ } RTC_TypeDef; /** * @brief Serial Audio Interface */ typedef struct { __IO uint32_t GCR; /*!< SAI global configuration register, Address offset: 0x00 */ uint32_t RESERVED0[16]; /*!< Reserved, 0x04 - 0x43 */ __IO uint32_t PDMCR; /*!< SAI PDM control register, Address offset: 0x44 */ __IO uint32_t PDMDLY; /*!< SAI PDM delay register, Address offset: 0x48 */ } SAI_TypeDef; typedef struct { __IO uint32_t CR1; /*!< SAI block x configuration register 1, Address offset: 0x04 */ __IO uint32_t CR2; /*!< SAI block x configuration register 2, Address offset: 0x08 */ __IO uint32_t FRCR; /*!< SAI block x frame configuration register, Address offset: 0x0C */ __IO uint32_t SLOTR; /*!< SAI block x slot register, Address offset: 0x10 */ __IO uint32_t IMR; /*!< SAI block x interrupt mask register, Address offset: 0x14 */ __IO uint32_t SR; /*!< SAI block x status register, Address offset: 0x18 */ __IO uint32_t CLRFR; /*!< SAI block x clear flag register, Address offset: 0x1C */ __IO uint32_t DR; /*!< SAI block x data register, Address offset: 0x20 */ } SAI_Block_TypeDef; /** * @brief SPDIF-RX Interface */ typedef struct { __IO uint32_t CR; /*!< Control register, Address offset: 0x00 */ __IO uint32_t IMR; /*!< Interrupt mask register, Address offset: 0x04 */ __IO uint32_t SR; /*!< Status register, Address offset: 0x08 */ __IO uint32_t IFCR; /*!< Interrupt Flag Clear register, Address offset: 0x0C */ __IO uint32_t DR; /*!< Data input register, Address offset: 0x10 */ __IO uint32_t CSR; /*!< Channel Status register, Address offset: 0x14 */ __IO uint32_t DIR; /*!< Debug Information register, Address offset: 0x18 */ uint32_t RESERVED2; /*!< Reserved, 0x1A */ } SPDIFRX_TypeDef; /** * @brief Secure digital input/output Interface */ typedef struct { __IO uint32_t POWER; /*!< SDMMC power control register, Address offset: 0x00 */ __IO uint32_t CLKCR; /*!< SDMMC clock control register, Address offset: 0x04 */ __IO uint32_t ARG; /*!< SDMMC argument register, Address offset: 0x08 */ __IO uint32_t CMD; /*!< SDMMC command register, Address offset: 0x0C */ __I uint32_t RESPCMD; /*!< SDMMC command response register, Address offset: 0x10 */ __I uint32_t RESP1; /*!< SDMMC response 1 register, Address offset: 0x14 */ __I uint32_t RESP2; /*!< SDMMC response 2 register, Address offset: 0x18 */ __I uint32_t RESP3; /*!< SDMMC response 3 register, Address offset: 0x1C */ __I uint32_t RESP4; /*!< SDMMC response 4 register, Address offset: 0x20 */ __IO uint32_t DTIMER; /*!< SDMMC data timer register, Address offset: 0x24 */ __IO uint32_t DLEN; /*!< SDMMC data length register, Address offset: 0x28 */ __IO uint32_t DCTRL; /*!< SDMMC data control register, Address offset: 0x2C */ __I uint32_t DCOUNT; /*!< SDMMC data counter register, Address offset: 0x30 */ __I uint32_t STA; /*!< SDMMC status register, Address offset: 0x34 */ __IO uint32_t ICR; /*!< SDMMC interrupt clear register, Address offset: 0x38 */ __IO uint32_t MASK; /*!< SDMMC mask register, Address offset: 0x3C */ __IO uint32_t ACKTIME; /*!< SDMMC Acknowledgement timer register, Address offset: 0x40 */ uint32_t RESERVED0[3]; /*!< Reserved, 0x44 - 0x4C - 0x4C */ __IO uint32_t IDMACTRL; /*!< SDMMC DMA control register, Address offset: 0x50 */ __IO uint32_t IDMABSIZE; /*!< SDMMC DMA buffer size register, Address offset: 0x54 */ __IO uint32_t IDMABASE0; /*!< SDMMC DMA buffer 0 base address register, Address offset: 0x58 */ __IO uint32_t IDMABASE1; /*!< SDMMC DMA buffer 1 base address register, Address offset: 0x5C */ uint32_t RESERVED1[8]; /*!< Reserved, 0x60-0x7C */ __IO uint32_t FIFO; /*!< SDMMC data FIFO register, Address offset: 0x80 */ uint32_t RESERVED2[222]; /*!< Reserved, 0x84-0x3F8 */ __IO uint32_t IPVR; /*!< SDMMC data FIFO register, Address offset: 0x3FC */ } SDMMC_TypeDef; /** * @brief Delay Block DLYB */ typedef struct { __IO uint32_t CR; /*!< DELAY BLOCK control register, Address offset: 0x00 */ __IO uint32_t CFGR; /*!< DELAY BLOCK configuration register, Address offset: 0x04 */ } DLYB_TypeDef; /** * @brief HW Semaphore HSEM */ typedef struct { __IO uint32_t R[32]; /*!< 2-step write lock and read back registers, Address offset: 00h-7Ch */ __IO uint32_t RLR[32]; /*!< 1-step read lock registers, Address offset: 80h-FCh */ __IO uint32_t C1IER; /*!< HSEM Interrupt enable register , Address offset: 100h */ __IO uint32_t C1ICR; /*!< HSEM Interrupt clear register , Address offset: 104h */ __IO uint32_t C1ISR; /*!< HSEM Interrupt Status register , Address offset: 108h */ __IO uint32_t C1MISR; /*!< HSEM Interrupt Masked Status register , Address offset: 10Ch */ uint32_t Reserved[12]; /* Reserved Address offset: 110h-13Ch */ __IO uint32_t CR; /*!< HSEM Semaphore clear register , Address offset: 140h */ __IO uint32_t KEYR; /*!< HSEM Semaphore clear key register , Address offset: 144h */ } HSEM_TypeDef; typedef struct { __IO uint32_t IER; /*!< HSEM interrupt enable register , Address offset: 0h */ __IO uint32_t ICR; /*!< HSEM interrupt clear register , Address offset: 4h */ __IO uint32_t ISR; /*!< HSEM interrupt status register , Address offset: 8h */ __IO uint32_t MISR; /*!< HSEM masked interrupt status register , Address offset: Ch */ } HSEM_Common_TypeDef; /** * @brief Serial Peripheral Interface */ typedef struct { __IO uint32_t CR1; /*!< SPI/I2S Control register 1, Address offset: 0x00 */ __IO uint32_t CR2; /*!< SPI Control register 2, Address offset: 0x04 */ __IO uint32_t CFG1; /*!< SPI Configuration register 1, Address offset: 0x08 */ __IO uint32_t CFG2; /*!< SPI Configuration register 2, Address offset: 0x0C */ __IO uint32_t IER; /*!< SPI/I2S Interrupt Enable register, Address offset: 0x10 */ __IO uint32_t SR; /*!< SPI/I2S Status register, Address offset: 0x14 */ __IO uint32_t IFCR; /*!< SPI/I2S Interrupt/Status flags clear register, Address offset: 0x18 */ uint32_t RESERVED0; /*!< Reserved, 0x1C */ __IO uint32_t TXDR; /*!< SPI/I2S Transmit data register, Address offset: 0x20 */ uint32_t RESERVED1[3]; /*!< Reserved, 0x24-0x2C */ __IO uint32_t RXDR; /*!< SPI/I2S Receive data register, Address offset: 0x30 */ uint32_t RESERVED2[3]; /*!< Reserved, 0x34-0x3C */ __IO uint32_t CRCPOLY; /*!< SPI CRC Polynomial register, Address offset: 0x40 */ __IO uint32_t TXCRC; /*!< SPI Transmitter CRC register, Address offset: 0x44 */ __IO uint32_t RXCRC; /*!< SPI Receiver CRC register, Address offset: 0x48 */ __IO uint32_t UDRDR; /*!< SPI Underrun data register, Address offset: 0x4C */ __IO uint32_t I2SCFGR; /*!< I2S Configuration register, Address offset: 0x50 */ } SPI_TypeDef; /** * @brief QUAD Serial Peripheral Interface */ typedef struct { __IO uint32_t CR; /*!< QUADSPI Control register, Address offset: 0x00 */ __IO uint32_t DCR; /*!< QUADSPI Device Configuration register, Address offset: 0x04 */ __IO uint32_t SR; /*!< QUADSPI Status register, Address offset: 0x08 */ __IO uint32_t FCR; /*!< QUADSPI Flag Clear register, Address offset: 0x0C */ __IO uint32_t DLR; /*!< QUADSPI Data Length register, Address offset: 0x10 */ __IO uint32_t CCR; /*!< QUADSPI Communication Configuration register, Address offset: 0x14 */ __IO uint32_t AR; /*!< QUADSPI Address register, Address offset: 0x18 */ __IO uint32_t ABR; /*!< QUADSPI Alternate Bytes register, Address offset: 0x1C */ __IO uint32_t DR; /*!< QUADSPI Data register, Address offset: 0x20 */ __IO uint32_t PSMKR; /*!< QUADSPI Polling Status Mask register, Address offset: 0x24 */ __IO uint32_t PSMAR; /*!< QUADSPI Polling Status Match register, Address offset: 0x28 */ __IO uint32_t PIR; /*!< QUADSPI Polling Interval register, Address offset: 0x2C */ __IO uint32_t LPTR; /*!< QUADSPI Low Power Timeout register, Address offset: 0x30 */ } QUADSPI_TypeDef; /** * @brief TIM */ typedef struct { __IO uint32_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ __IO uint32_t CR2; /*!< TIM control register 2, Address offset: 0x04 */ __IO uint32_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */ __IO uint32_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */ __IO uint32_t SR; /*!< TIM status register, Address offset: 0x10 */ __IO uint32_t EGR; /*!< TIM event generation register, Address offset: 0x14 */ __IO uint32_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */ __IO uint32_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */ __IO uint32_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */ __IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */ __IO uint32_t PSC; /*!< TIM prescaler, Address offset: 0x28 */ __IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */ __IO uint32_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */ __IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */ __IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */ __IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */ __IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */ __IO uint32_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */ __IO uint32_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */ __IO uint32_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x4C */ uint32_t RESERVED1; /*!< Reserved, 0x50 */ __IO uint32_t CCMR3; /*!< TIM capture/compare mode register 3, Address offset: 0x54 */ __IO uint32_t CCR5; /*!< TIM capture/compare register5, Address offset: 0x58 */ __IO uint32_t CCR6; /*!< TIM capture/compare register6, Address offset: 0x5C */ __IO uint32_t AF1; /*!< TIM alternate function option register 1, Address offset: 0x60 */ __IO uint32_t AF2; /*!< TIM alternate function option register 2, Address offset: 0x64 */ __IO uint32_t TISEL; /*!< TIM Input Selection register, Address offset: 0x68 */ } TIM_TypeDef; /** * @brief LPTIMIMER */ typedef struct { __IO uint32_t ISR; /*!< LPTIM Interrupt and Status register, Address offset: 0x00 */ __IO uint32_t ICR; /*!< LPTIM Interrupt Clear register, Address offset: 0x04 */ __IO uint32_t IER; /*!< LPTIM Interrupt Enable register, Address offset: 0x08 */ __IO uint32_t CFGR; /*!< LPTIM Configuration register, Address offset: 0x0C */ __IO uint32_t CR; /*!< LPTIM Control register, Address offset: 0x10 */ __IO uint32_t CMP; /*!< LPTIM Compare register, Address offset: 0x14 */ __IO uint32_t ARR; /*!< LPTIM Autoreload register, Address offset: 0x18 */ __IO uint32_t CNT; /*!< LPTIM Counter register, Address offset: 0x1C */ uint32_t RESERVED1; /*!< Reserved, 0x20 */ __IO uint32_t CFGR2; /*!< LPTIM Configuration register, Address offset: 0x24 */ } LPTIM_TypeDef; /** * @brief Comparator */ typedef struct { __IO uint32_t SR; /*!< Comparator status register, Address offset: 0x00 */ __IO uint32_t ICFR; /*!< Comparator interrupt clear flag register, Address offset: 0x04 */ __IO uint32_t OR; /*!< Comparator option register, Address offset: 0x08 */ } COMPOPT_TypeDef; typedef struct { __IO uint32_t CFGR; /*!< Comparator configuration register , Address offset: 0x00 */ } COMP_TypeDef; typedef struct { __IO uint32_t CFGR; /*!< COMP control and status register, used for bits common to several COMP instances, Address offset: 0x00 */ } COMP_Common_TypeDef; /** * @brief Universal Synchronous Asynchronous Receiver Transmitter */ typedef struct { __IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x00 */ __IO uint32_t CR2; /*!< USART Control register 2, Address offset: 0x04 */ __IO uint32_t CR3; /*!< USART Control register 3, Address offset: 0x08 */ __IO uint32_t BRR; /*!< USART Baud rate register, Address offset: 0x0C */ __IO uint32_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x10 */ __IO uint32_t RTOR; /*!< USART Receiver Time Out register, Address offset: 0x14 */ __IO uint32_t RQR; /*!< USART Request register, Address offset: 0x18 */ __IO uint32_t ISR; /*!< USART Interrupt and status register, Address offset: 0x1C */ __IO uint32_t ICR; /*!< USART Interrupt flag Clear register, Address offset: 0x20 */ __IO uint32_t RDR; /*!< USART Receive Data register, Address offset: 0x24 */ __IO uint32_t TDR; /*!< USART Transmit Data register, Address offset: 0x28 */ __IO uint32_t PRESC; /*!< USART clock Prescaler register, Address offset: 0x2C */ } USART_TypeDef; /** * @brief Single Wire Protocol Master Interface SPWMI */ typedef struct { __IO uint32_t CR; /*!< SWPMI Configuration/Control register, Address offset: 0x00 */ __IO uint32_t BRR; /*!< SWPMI bitrate register, Address offset: 0x04 */ uint32_t RESERVED1; /*!< Reserved, 0x08 */ __IO uint32_t ISR; /*!< SWPMI Interrupt and Status register, Address offset: 0x0C */ __IO uint32_t ICR; /*!< SWPMI Interrupt Flag Clear register, Address offset: 0x10 */ __IO uint32_t IER; /*!< SWPMI Interrupt Enable register, Address offset: 0x14 */ __IO uint32_t RFL; /*!< SWPMI Receive Frame Length register, Address offset: 0x18 */ __IO uint32_t TDR; /*!< SWPMI Transmit data register, Address offset: 0x1C */ __IO uint32_t RDR; /*!< SWPMI Receive data register, Address offset: 0x20 */ __IO uint32_t OR; /*!< SWPMI Option register, Address offset: 0x24 */ } SWPMI_TypeDef; /** * @brief Window WATCHDOG */ typedef struct { __IO uint32_t CR; /*!< WWDG Control register, Address offset: 0x00 */ __IO uint32_t CFR; /*!< WWDG Configuration register, Address offset: 0x04 */ __IO uint32_t SR; /*!< WWDG Status register, Address offset: 0x08 */ } WWDG_TypeDef; /** * @brief RAM_ECC_Specific_Registers */ typedef struct { __IO uint32_t CR; /*!< RAMECC monitor configuration register */ __IO uint32_t SR; /*!< RAMECC monitor status register */ __IO uint32_t FAR; /*!< RAMECC monitor failing address register */ __IO uint32_t FDRL; /*!< RAMECC monitor failing data low register */ __IO uint32_t FDRH; /*!< RAMECC monitor failing data high register */ __IO uint32_t FECR; /*!< RAMECC monitor failing ECC error code register */ } RAMECC_MonitorTypeDef; typedef struct { __IO uint32_t IER; /*!< RAMECC interrupt enable register */ } RAMECC_TypeDef; /** * @} */ /** * @brief High resolution Timer (HRTIM) */ /* HRTIM master registers definition */ typedef struct { __IO uint32_t MCR; /*!< HRTIM Master Timer control register, Address offset: 0x00 */ __IO uint32_t MISR; /*!< HRTIM Master Timer interrupt status register, Address offset: 0x04 */ __IO uint32_t MICR; /*!< HRTIM Master Timer interrupt clear register, Address offset: 0x08 */ __IO uint32_t MDIER; /*!< HRTIM Master Timer DMA/interrupt enable register Address offset: 0x0C */ __IO uint32_t MCNTR; /*!< HRTIM Master Timer counter register, Address offset: 0x10 */ __IO uint32_t MPER; /*!< HRTIM Master Timer period register, Address offset: 0x14 */ __IO uint32_t MREP; /*!< HRTIM Master Timer repetition register, Address offset: 0x18 */ __IO uint32_t MCMP1R; /*!< HRTIM Master Timer compare 1 register, Address offset: 0x1C */ uint32_t RESERVED0; /*!< Reserved, 0x20 */ __IO uint32_t MCMP2R; /*!< HRTIM Master Timer compare 2 register, Address offset: 0x24 */ __IO uint32_t MCMP3R; /*!< HRTIM Master Timer compare 3 register, Address offset: 0x28 */ __IO uint32_t MCMP4R; /*!< HRTIM Master Timer compare 4 register, Address offset: 0x2C */ uint32_t RESERVED1[20]; /*!< Reserved, 0x30..0x7C */ }HRTIM_Master_TypeDef; /* HRTIM Timer A to E registers definition */ typedef struct { __IO uint32_t TIMxCR; /*!< HRTIM Timerx control register, Address offset: 0x00 */ __IO uint32_t TIMxISR; /*!< HRTIM Timerx interrupt status register, Address offset: 0x04 */ __IO uint32_t TIMxICR; /*!< HRTIM Timerx interrupt clear register, Address offset: 0x08 */ __IO uint32_t TIMxDIER; /*!< HRTIM Timerx DMA/interrupt enable register, Address offset: 0x0C */ __IO uint32_t CNTxR; /*!< HRTIM Timerx counter register, Address offset: 0x10 */ __IO uint32_t PERxR; /*!< HRTIM Timerx period register, Address offset: 0x14 */ __IO uint32_t REPxR; /*!< HRTIM Timerx repetition register, Address offset: 0x18 */ __IO uint32_t CMP1xR; /*!< HRTIM Timerx compare 1 register, Address offset: 0x1C */ __IO uint32_t CMP1CxR; /*!< HRTIM Timerx compare 1 compound register, Address offset: 0x20 */ __IO uint32_t CMP2xR; /*!< HRTIM Timerx compare 2 register, Address offset: 0x24 */ __IO uint32_t CMP3xR; /*!< HRTIM Timerx compare 3 register, Address offset: 0x28 */ __IO uint32_t CMP4xR; /*!< HRTIM Timerx compare 4 register, Address offset: 0x2C */ __IO uint32_t CPT1xR; /*!< HRTIM Timerx capture 1 register, Address offset: 0x30 */ __IO uint32_t CPT2xR; /*!< HRTIM Timerx capture 2 register, Address offset: 0x34 */ __IO uint32_t DTxR; /*!< HRTIM Timerx dead time register, Address offset: 0x38 */ __IO uint32_t SETx1R; /*!< HRTIM Timerx output 1 set register, Address offset: 0x3C */ __IO uint32_t RSTx1R; /*!< HRTIM Timerx output 1 reset register, Address offset: 0x40 */ __IO uint32_t SETx2R; /*!< HRTIM Timerx output 2 set register, Address offset: 0x44 */ __IO uint32_t RSTx2R; /*!< HRTIM Timerx output 2 reset register, Address offset: 0x48 */ __IO uint32_t EEFxR1; /*!< HRTIM Timerx external event filtering 1 register, Address offset: 0x4C */ __IO uint32_t EEFxR2; /*!< HRTIM Timerx external event filtering 2 register, Address offset: 0x50 */ __IO uint32_t RSTxR; /*!< HRTIM Timerx Reset register, Address offset: 0x54 */ __IO uint32_t CHPxR; /*!< HRTIM Timerx Chopper register, Address offset: 0x58 */ __IO uint32_t CPT1xCR; /*!< HRTIM Timerx Capture 1 register, Address offset: 0x5C */ __IO uint32_t CPT2xCR; /*!< HRTIM Timerx Capture 2 register, Address offset: 0x60 */ __IO uint32_t OUTxR; /*!< HRTIM Timerx Output register, Address offset: 0x64 */ __IO uint32_t FLTxR; /*!< HRTIM Timerx Fault register, Address offset: 0x68 */ uint32_t RESERVED0[5]; /*!< Reserved, 0x6C..0x7C */ }HRTIM_Timerx_TypeDef; /* HRTIM common register definition */ typedef struct { __IO uint32_t CR1; /*!< HRTIM control register1, Address offset: 0x00 */ __IO uint32_t CR2; /*!< HRTIM control register2, Address offset: 0x04 */ __IO uint32_t ISR; /*!< HRTIM interrupt status register, Address offset: 0x08 */ __IO uint32_t ICR; /*!< HRTIM interrupt clear register, Address offset: 0x0C */ __IO uint32_t IER; /*!< HRTIM interrupt enable register, Address offset: 0x10 */ __IO uint32_t OENR; /*!< HRTIM Output enable register, Address offset: 0x14 */ __IO uint32_t ODISR; /*!< HRTIM Output disable register, Address offset: 0x18 */ __IO uint32_t ODSR; /*!< HRTIM Output disable status register, Address offset: 0x1C */ __IO uint32_t BMCR; /*!< HRTIM Burst mode control register, Address offset: 0x20 */ __IO uint32_t BMTRGR; /*!< HRTIM Burst mode trigger register, Address offset: 0x24 */ __IO uint32_t BMCMPR; /*!< HRTIM Burst mode compare register, Address offset: 0x28 */ __IO uint32_t BMPER; /*!< HRTIM Burst mode period register, Address offset: 0x2C */ __IO uint32_t EECR1; /*!< HRTIM Timer external event control register1, Address offset: 0x30 */ __IO uint32_t EECR2; /*!< HRTIM Timer external event control register2, Address offset: 0x34 */ __IO uint32_t EECR3; /*!< HRTIM Timer external event control register3, Address offset: 0x38 */ __IO uint32_t ADC1R; /*!< HRTIM ADC Trigger 1 register, Address offset: 0x3C */ __IO uint32_t ADC2R; /*!< HRTIM ADC Trigger 2 register, Address offset: 0x40 */ __IO uint32_t ADC3R; /*!< HRTIM ADC Trigger 3 register, Address offset: 0x44 */ __IO uint32_t ADC4R; /*!< HRTIM ADC Trigger 4 register, Address offset: 0x48 */ __IO uint32_t RESERVED0; /*!< Reserved, Address offset: 0x4C */ __IO uint32_t FLTINR1; /*!< HRTIM Fault input register1, Address offset: 0x50 */ __IO uint32_t FLTINR2; /*!< HRTIM Fault input register2, Address offset: 0x54 */ __IO uint32_t BDMUPR; /*!< HRTIM Burst DMA Master Timer update register, Address offset: 0x58 */ __IO uint32_t BDTAUPR; /*!< HRTIM Burst DMA Timerx update register, Address offset: 0x5C */ __IO uint32_t BDTBUPR; /*!< HRTIM Burst DMA Timerx update register, Address offset: 0x60 */ __IO uint32_t BDTCUPR; /*!< HRTIM Burst DMA Timerx update register, Address offset: 0x64 */ __IO uint32_t BDTDUPR; /*!< HRTIM Burst DMA Timerx update register, Address offset: 0x68 */ __IO uint32_t BDTEUPR; /*!< HRTIM Burst DMA Timerx update register, Address offset: 0x6C */ __IO uint32_t BDMADR; /*!< HRTIM Burst DMA Master Data register, Address offset: 0x70 */ }HRTIM_Common_TypeDef; /* HRTIM register definition */ typedef struct { HRTIM_Master_TypeDef sMasterRegs; HRTIM_Timerx_TypeDef sTimerxRegs[5]; uint32_t RESERVED0[32]; HRTIM_Common_TypeDef sCommonRegs; }HRTIM_TypeDef; /** * @brief RNG */ typedef struct { __IO uint32_t CR; /*!< RNG control register, Address offset: 0x00 */ __IO uint32_t SR; /*!< RNG status register, Address offset: 0x04 */ __IO uint32_t DR; /*!< RNG data register, Address offset: 0x08 */ } RNG_TypeDef; /** * @brief MDIOS */ typedef struct { __IO uint32_t CR; __IO uint32_t WRFR; __IO uint32_t CWRFR; __IO uint32_t RDFR; __IO uint32_t CRDFR; __IO uint32_t SR; __IO uint32_t CLRFR; uint32_t RESERVED[57]; __IO uint32_t DINR0; __IO uint32_t DINR1; __IO uint32_t DINR2; __IO uint32_t DINR3; __IO uint32_t DINR4; __IO uint32_t DINR5; __IO uint32_t DINR6; __IO uint32_t DINR7; __IO uint32_t DINR8; __IO uint32_t DINR9; __IO uint32_t DINR10; __IO uint32_t DINR11; __IO uint32_t DINR12; __IO uint32_t DINR13; __IO uint32_t DINR14; __IO uint32_t DINR15; __IO uint32_t DINR16; __IO uint32_t DINR17; __IO uint32_t DINR18; __IO uint32_t DINR19; __IO uint32_t DINR20; __IO uint32_t DINR21; __IO uint32_t DINR22; __IO uint32_t DINR23; __IO uint32_t DINR24; __IO uint32_t DINR25; __IO uint32_t DINR26; __IO uint32_t DINR27; __IO uint32_t DINR28; __IO uint32_t DINR29; __IO uint32_t DINR30; __IO uint32_t DINR31; __IO uint32_t DOUTR0; __IO uint32_t DOUTR1; __IO uint32_t DOUTR2; __IO uint32_t DOUTR3; __IO uint32_t DOUTR4; __IO uint32_t DOUTR5; __IO uint32_t DOUTR6; __IO uint32_t DOUTR7; __IO uint32_t DOUTR8; __IO uint32_t DOUTR9; __IO uint32_t DOUTR10; __IO uint32_t DOUTR11; __IO uint32_t DOUTR12; __IO uint32_t DOUTR13; __IO uint32_t DOUTR14; __IO uint32_t DOUTR15; __IO uint32_t DOUTR16; __IO uint32_t DOUTR17; __IO uint32_t DOUTR18; __IO uint32_t DOUTR19; __IO uint32_t DOUTR20; __IO uint32_t DOUTR21; __IO uint32_t DOUTR22; __IO uint32_t DOUTR23; __IO uint32_t DOUTR24; __IO uint32_t DOUTR25; __IO uint32_t DOUTR26; __IO uint32_t DOUTR27; __IO uint32_t DOUTR28; __IO uint32_t DOUTR29; __IO uint32_t DOUTR30; __IO uint32_t DOUTR31; } MDIOS_TypeDef; /** * @brief USB_OTG_Core_Registers */ typedef struct { __IO uint32_t GOTGCTL; /*!< USB_OTG Control and Status Register 000h */ __IO uint32_t GOTGINT; /*!< USB_OTG Interrupt Register 004h */ __IO uint32_t GAHBCFG; /*!< Core AHB Configuration Register 008h */ __IO uint32_t GUSBCFG; /*!< Core USB Configuration Register 00Ch */ __IO uint32_t GRSTCTL; /*!< Core Reset Register 010h */ __IO uint32_t GINTSTS; /*!< Core Interrupt Register 014h */ __IO uint32_t GINTMSK; /*!< Core Interrupt Mask Register 018h */ __IO uint32_t GRXSTSR; /*!< Receive Sts Q Read Register 01Ch */ __IO uint32_t GRXSTSP; /*!< Receive Sts Q Read & POP Register 020h */ __IO uint32_t GRXFSIZ; /*!< Receive FIFO Size Register 024h */ __IO uint32_t DIEPTXF0_HNPTXFSIZ; /*!< EP0 / Non Periodic Tx FIFO Size Register 028h */ __IO uint32_t HNPTXSTS; /*!< Non Periodic Tx FIFO/Queue Sts reg 02Ch */ uint32_t Reserved30[2]; /*!< Reserved 030h */ __IO uint32_t GCCFG; /*!< General Purpose IO Register 038h */ __IO uint32_t CID; /*!< User ID Register 03Ch */ __IO uint32_t GSNPSID; /* USB_OTG core ID 040h*/ __IO uint32_t GHWCFG1; /* User HW config1 044h*/ __IO uint32_t GHWCFG2; /* User HW config2 048h*/ __IO uint32_t GHWCFG3; /*!< User HW config3 04Ch */ uint32_t Reserved6; /*!< Reserved 050h */ __IO uint32_t GLPMCFG; /*!< LPM Register 054h */ __IO uint32_t GPWRDN; /*!< Power Down Register 058h */ __IO uint32_t GDFIFOCFG; /*!< DFIFO Software Config Register 05Ch */ __IO uint32_t GADPCTL; /*!< ADP Timer, Control and Status Register 60Ch */ uint32_t Reserved43[39]; /*!< Reserved 058h-0FFh */ __IO uint32_t HPTXFSIZ; /*!< Host Periodic Tx FIFO Size Reg 100h */ __IO uint32_t DIEPTXF[0x0F]; /*!< dev Periodic Transmit FIFO */ } USB_OTG_GlobalTypeDef; /** * @brief USB_OTG_device_Registers */ typedef struct { __IO uint32_t DCFG; /*!< dev Configuration Register 800h */ __IO uint32_t DCTL; /*!< dev Control Register 804h */ __IO uint32_t DSTS; /*!< dev Status Register (RO) 808h */ uint32_t Reserved0C; /*!< Reserved 80Ch */ __IO uint32_t DIEPMSK; /*!< dev IN Endpoint Mask 810h */ __IO uint32_t DOEPMSK; /*!< dev OUT Endpoint Mask 814h */ __IO uint32_t DAINT; /*!< dev All Endpoints Itr Reg 818h */ __IO uint32_t DAINTMSK; /*!< dev All Endpoints Itr Mask 81Ch */ uint32_t Reserved20; /*!< Reserved 820h */ uint32_t Reserved9; /*!< Reserved 824h */ __IO uint32_t DVBUSDIS; /*!< dev VBUS discharge Register 828h */ __IO uint32_t DVBUSPULSE; /*!< dev VBUS Pulse Register 82Ch */ __IO uint32_t DTHRCTL; /*!< dev threshold 830h */ __IO uint32_t DIEPEMPMSK; /*!< dev empty msk 834h */ __IO uint32_t DEACHINT; /*!< dedicated EP interrupt 838h */ __IO uint32_t DEACHMSK; /*!< dedicated EP msk 83Ch */ uint32_t Reserved40; /*!< dedicated EP mask 840h */ __IO uint32_t DINEP1MSK; /*!< dedicated EP mask 844h */ uint32_t Reserved44[15]; /*!< Reserved 844-87Ch */ __IO uint32_t DOUTEP1MSK; /*!< dedicated EP msk 884h */ } USB_OTG_DeviceTypeDef; /** * @brief USB_OTG_IN_Endpoint-Specific_Register */ typedef struct { __IO uint32_t DIEPCTL; /*!< dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h */ uint32_t Reserved04; /*!< Reserved 900h + (ep_num * 20h) + 04h */ __IO uint32_t DIEPINT; /*!< dev IN Endpoint Itr Reg 900h + (ep_num * 20h) + 08h */ uint32_t Reserved0C; /*!< Reserved 900h + (ep_num * 20h) + 0Ch */ __IO uint32_t DIEPTSIZ; /*!< IN Endpoint Txfer Size 900h + (ep_num * 20h) + 10h */ __IO uint32_t DIEPDMA; /*!< IN Endpoint DMA Address Reg 900h + (ep_num * 20h) + 14h */ __IO uint32_t DTXFSTS; /*!< IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h */ uint32_t Reserved18; /*!< Reserved 900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch */ } USB_OTG_INEndpointTypeDef; /** * @brief USB_OTG_OUT_Endpoint-Specific_Registers */ typedef struct { __IO uint32_t DOEPCTL; /*!< dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h */ uint32_t Reserved04; /*!< Reserved B00h + (ep_num * 20h) + 04h */ __IO uint32_t DOEPINT; /*!< dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h */ uint32_t Reserved0C; /*!< Reserved B00h + (ep_num * 20h) + 0Ch */ __IO uint32_t DOEPTSIZ; /*!< dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h */ __IO uint32_t DOEPDMA; /*!< dev OUT Endpoint DMA Address B00h + (ep_num * 20h) + 14h */ uint32_t Reserved18[2]; /*!< Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch */ } USB_OTG_OUTEndpointTypeDef; /** * @brief USB_OTG_Host_Mode_Register_Structures */ typedef struct { __IO uint32_t HCFG; /*!< Host Configuration Register 400h */ __IO uint32_t HFIR; /*!< Host Frame Interval Register 404h */ __IO uint32_t HFNUM; /*!< Host Frame Nbr/Frame Remaining 408h */ uint32_t Reserved40C; /*!< Reserved 40Ch */ __IO uint32_t HPTXSTS; /*!< Host Periodic Tx FIFO/ Queue Status 410h */ __IO uint32_t HAINT; /*!< Host All Channels Interrupt Register 414h */ __IO uint32_t HAINTMSK; /*!< Host All Channels Interrupt Mask 418h */ } USB_OTG_HostTypeDef; /** * @brief USB_OTG_Host_Channel_Specific_Registers */ typedef struct { __IO uint32_t HCCHAR; /*!< Host Channel Characteristics Register 500h */ __IO uint32_t HCSPLT; /*!< Host Channel Split Control Register 504h */ __IO uint32_t HCINT; /*!< Host Channel Interrupt Register 508h */ __IO uint32_t HCINTMSK; /*!< Host Channel Interrupt Mask Register 50Ch */ __IO uint32_t HCTSIZ; /*!< Host Channel Transfer Size Register 510h */ __IO uint32_t HCDMA; /*!< Host Channel DMA Address Register 514h */ uint32_t Reserved[2]; /*!< Reserved */ } USB_OTG_HostChannelTypeDef; /** * @} */ /** * @brief Global Programmer View */ typedef struct { uint32_t RESERVED0[2036]; /*!< Reserved, Address offset: 0x00-0x1FCC */ __IO uint32_t AXI_PERIPH_ID_4; /*!< AXI interconnect - peripheral ID4 register, Address offset: 0x1FD0 */ uint32_t AXI_PERIPH_ID_5; /*!< Reserved, Address offset: 0x1FD4 */ uint32_t AXI_PERIPH_ID_6; /*!< Reserved, Address offset: 0x1FD8 */ uint32_t AXI_PERIPH_ID_7; /*!< Reserved, Address offset: 0x1FDC */ __IO uint32_t AXI_PERIPH_ID_0; /*!< AXI interconnect - peripheral ID0 register, Address offset: 0x1FE0 */ __IO uint32_t AXI_PERIPH_ID_1; /*!< AXI interconnect - peripheral ID1 register, Address offset: 0x1FE4 */ __IO uint32_t AXI_PERIPH_ID_2; /*!< AXI interconnect - peripheral ID2 register, Address offset: 0x1FE8 */ __IO uint32_t AXI_PERIPH_ID_3; /*!< AXI interconnect - peripheral ID3 register, Address offset: 0x1FEC */ __IO uint32_t AXI_COMP_ID_0; /*!< AXI interconnect - component ID0 register, Address offset: 0x1FF0 */ __IO uint32_t AXI_COMP_ID_1; /*!< AXI interconnect - component ID1 register, Address offset: 0x1FF4 */ __IO uint32_t AXI_COMP_ID_2; /*!< AXI interconnect - component ID2 register, Address offset: 0x1FF8 */ __IO uint32_t AXI_COMP_ID_3; /*!< AXI interconnect - component ID3 register, Address offset: 0x1FFC */ uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x2000-0x2004 */ __IO uint32_t AXI_TARG1_FN_MOD_ISS_BM; /*!< AXI interconnect - TARG 1 bus matrix issuing functionality register, Address offset: 0x2008 */ uint32_t RESERVED2[6]; /*!< Reserved, Address offset: 0x200C-0x2020 */ __IO uint32_t AXI_TARG1_FN_MOD2; /*!< AXI interconnect - TARG 1 bus matrix functionality 2 register, Address offset: 0x2024 */ uint32_t RESERVED3; /*!< Reserved, Address offset: 0x2028 */ __IO uint32_t AXI_TARG1_FN_MOD_LB; /*!< AXI interconnect - TARG 1 long burst functionality modification register, Address offset: 0x202C */ uint32_t RESERVED4[54]; /*!< Reserved, Address offset: 0x2030-0x2104 */ __IO uint32_t AXI_TARG1_FN_MOD; /*!< AXI interconnect - TARG 1 issuing functionality modification register, Address offset: 0x2108 */ uint32_t RESERVED5[959]; /*!< Reserved, Address offset: 0x210C-0x3004 */ __IO uint32_t AXI_TARG2_FN_MOD_ISS_BM; /*!< AXI interconnect - TARG 2 bus matrix issuing functionality register, Address offset: 0x3008 */ uint32_t RESERVED6[6]; /*!< Reserved, Address offset: 0x300C-0x3020 */ __IO uint32_t AXI_TARG2_FN_MOD2; /*!< AXI interconnect - TARG 2 bus matrix functionality 2 register, Address offset: 0x3024 */ uint32_t RESERVED7; /*!< Reserved, Address offset: 0x3028 */ __IO uint32_t AXI_TARG2_FN_MOD_LB; /*!< AXI interconnect - TARG 2 long burst functionality modification register, Address offset: 0x302C */ uint32_t RESERVED8[54]; /*!< Reserved, Address offset: 0x3030-0x3104 */ __IO uint32_t AXI_TARG2_FN_MOD; /*!< AXI interconnect - TARG 2 issuing functionality modification register, Address offset: 0x3108 */ uint32_t RESERVED9[959]; /*!< Reserved, Address offset: 0x310C-0x4004 */ __IO uint32_t AXI_TARG3_FN_MOD_ISS_BM; /*!< AXI interconnect - TARG 3 bus matrix issuing functionality register, Address offset: 0x4008 */ uint32_t RESERVED10[1023]; /*!< Reserved, Address offset: 0x400C-0x5004 */ __IO uint32_t AXI_TARG4_FN_MOD_ISS_BM; /*!< AXI interconnect - TARG 4 bus matrix issuing functionality register, Address offset: 0x5008 */ uint32_t RESERVED11[1023]; /*!< Reserved, Address offset: 0x500C-0x6004 */ __IO uint32_t AXI_TARG5_FN_MOD_ISS_BM; /*!< AXI interconnect - TARG 5 bus matrix issuing functionality register, Address offset: 0x6008 */ uint32_t RESERVED12[1023]; /*!< Reserved, Address offset: 0x600C-0x7004 */ __IO uint32_t AXI_TARG6_FN_MOD_ISS_BM; /*!< AXI interconnect - TARG 6 bus matrix issuing functionality register, Address offset: 0x7008 */ uint32_t RESERVED13[1023]; /*!< Reserved, Address offset: 0x700C-0x8004 */ __IO uint32_t AXI_TARG7_FN_MOD_ISS_BM; /*!< AXI interconnect - TARG 7 bus matrix issuing functionality register, Address offset: 0x8008 */ uint32_t RESERVED14[6]; /*!< Reserved, Address offset: 0x800C-0x8020 */ __IO uint32_t AXI_TARG7_FN_MOD2; /*!< AXI interconnect - TARG 7 bus matrix functionality 2 register, Address offset: 0x8024 */ uint32_t RESERVED15; /*!< Reserved, Address offset: 0x8028 */ __IO uint32_t AXI_TARG7_FN_MOD_LB; /*!< AXI interconnect - TARG 7 long burst functionality modification register, Address offset: 0x802C */ uint32_t RESERVED16[54]; /*!< Reserved, Address offset: 0x8030-0x8104 */ __IO uint32_t AXI_TARG7_FN_MOD; /*!< AXI interconnect - TARG 7 issuing functionality modification register, Address offset: 0x8108 */ uint32_t RESERVED17[59334]; /*!< Reserved, Address offset: 0x810C-0x42020 */ __IO uint32_t AXI_INI1_FN_MOD2; /*!< AXI interconnect - INI 1 functionality modification 2 register, Address offset: 0x42024 */ __IO uint32_t AXI_INI1_FN_MOD_AHB; /*!< AXI interconnect - INI 1 AHB functionality modification register, Address offset: 0x42028 */ uint32_t RESERVED18[53]; /*!< Reserved, Address offset: 0x4202C-0x420FC */ __IO uint32_t AXI_INI1_READ_QOS; /*!< AXI interconnect - INI 1 read QoS register, Address offset: 0x42100 */ __IO uint32_t AXI_INI1_WRITE_QOS; /*!< AXI interconnect - INI 1 write QoS register, Address offset: 0x42104 */ __IO uint32_t AXI_INI1_FN_MOD; /*!< AXI interconnect - INI 1 issuing functionality modification register, Address offset: 0x42108 */ uint32_t RESERVED19[1021]; /*!< Reserved, Address offset: 0x4210C-0x430FC */ __IO uint32_t AXI_INI2_READ_QOS; /*!< AXI interconnect - INI 2 read QoS register, Address offset: 0x43100 */ __IO uint32_t AXI_INI2_WRITE_QOS; /*!< AXI interconnect - INI 2 write QoS register, Address offset: 0x43104 */ __IO uint32_t AXI_INI2_FN_MOD; /*!< AXI interconnect - INI 2 issuing functionality modification register, Address offset: 0x43108 */ uint32_t RESERVED20[966]; /*!< Reserved, Address offset: 0x4310C-0x44020 */ __IO uint32_t AXI_INI3_FN_MOD2; /*!< AXI interconnect - INI 3 functionality modification 2 register, Address offset: 0x44024 */ __IO uint32_t AXI_INI3_FN_MOD_AHB; /*!< AXI interconnect - INI 3 AHB functionality modification register, Address offset: 0x44028 */ uint32_t RESERVED21[53]; /*!< Reserved, Address offset: 0x4402C-0x440FC */ __IO uint32_t AXI_INI3_READ_QOS; /*!< AXI interconnect - INI 3 read QoS register, Address offset: 0x44100 */ __IO uint32_t AXI_INI3_WRITE_QOS; /*!< AXI interconnect - INI 3 write QoS register, Address offset: 0x44104 */ __IO uint32_t AXI_INI3_FN_MOD; /*!< AXI interconnect - INI 3 issuing functionality modification register, Address offset: 0x44108 */ uint32_t RESERVED22[1021]; /*!< Reserved, Address offset: 0x4410C-0x450FC */ __IO uint32_t AXI_INI4_READ_QOS; /*!< AXI interconnect - INI 4 read QoS register, Address offset: 0x45100 */ __IO uint32_t AXI_INI4_WRITE_QOS; /*!< AXI interconnect - INI 4 write QoS register, Address offset: 0x45104 */ __IO uint32_t AXI_INI4_FN_MOD; /*!< AXI interconnect - INI 4 issuing functionality modification register, Address offset: 0x45108 */ uint32_t RESERVED23[1021]; /*!< Reserved, Address offset: 0x4510C-0x460FC */ __IO uint32_t AXI_INI5_READ_QOS; /*!< AXI interconnect - INI 5 read QoS register, Address offset: 0x46100 */ __IO uint32_t AXI_INI5_WRITE_QOS; /*!< AXI interconnect - INI 5 write QoS register, Address offset: 0x46104 */ __IO uint32_t AXI_INI5_FN_MOD; /*!< AXI interconnect - INI 5 issuing functionality modification register, Address offset: 0x46108 */ uint32_t RESERVED24[1021]; /*!< Reserved, Address offset: 0x4610C-0x470FC */ __IO uint32_t AXI_INI6_READ_QOS; /*!< AXI interconnect - INI 6 read QoS register, Address offset: 0x47100 */ __IO uint32_t AXI_INI6_WRITE_QOS; /*!< AXI interconnect - INI 6 write QoS register, Address offset: 0x47104 */ __IO uint32_t AXI_INI6_FN_MOD; /*!< AXI interconnect - INI 6 issuing functionality modification register, Address offset: 0x47108 */ } GPV_TypeDef; /** @addtogroup Peripheral_memory_map * @{ */ #define D1_ITCMRAM_BASE (0x00000000UL) /*!< Base address of : 64KB RAM reserved for CPU execution/instruction accessible over ITCM */ #define D1_ITCMICP_BASE (0x00100000UL) /*!< Base address of : (up to 128KB) embedded Test FLASH memory accessible over ITCM */ #define D1_DTCMRAM_BASE (0x20000000UL) /*!< Base address of : 128KB system data RAM accessible over DTCM */ #define D1_AXIFLASH_BASE (0x08000000UL) /*!< Base address of : (up to 2 MB) embedded FLASH memory accessible over AXI */ #define D1_AXIICP_BASE (0x1FF00000UL) /*!< Base address of : (up to 128KB) embedded Test FLASH memory accessible over AXI */ #define D1_AXISRAM_BASE (0x24000000UL) /*!< Base address of : (up to 512KB) system data RAM accessible over over AXI */ #define D2_AXISRAM_BASE (0x10000000UL) /*!< Base address of : (up to 288KB) system data RAM accessible over over AXI */ #define D2_AHBSRAM_BASE (0x30000000UL) /*!< Base address of : (up to 288KB) system data RAM accessible over over AXI->AHB Bridge */ #define D3_BKPSRAM_BASE (0x38800000UL) /*!< Base address of : Backup SRAM(4 KB) over AXI->AHB Bridge */ #define D3_SRAM_BASE (0x38000000UL) /*!< Base address of : Backup SRAM(64 KB) over AXI->AHB Bridge */ #define PERIPH_BASE (0x40000000UL) /*!< Base address of : AHB/APB Peripherals */ #define QSPI_BASE (0x90000000UL) /*!< Base address of : QSPI memories accessible over AXI */ #define FLASH_BANK1_BASE (0x08000000UL) /*!< Base address of : (up to 1 MB) Flash Bank1 accessible over AXI */ #define FLASH_BANK2_BASE (0x08100000UL) /*!< Base address of : (up to 1 MB) Flash Bank2 accessible over AXI */ #define FLASH_END (0x081FFFFFUL) /*!< FLASH end address */ /* Legacy define */ #define FLASH_BASE FLASH_BANK1_BASE /*!< Device electronic signature memory map */ #define UID_BASE (0x1FF1E800UL) /*!< Unique device ID register base address */ #define FLASHSIZE_BASE (0x1FF1E880UL) /*!< FLASH Size register base address */ /*!< Peripheral memory map */ #define D2_APB1PERIPH_BASE PERIPH_BASE #define D2_APB2PERIPH_BASE (PERIPH_BASE + 0x00010000UL) #define D2_AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000UL) #define D2_AHB2PERIPH_BASE (PERIPH_BASE + 0x08020000UL) #define D1_APB1PERIPH_BASE (PERIPH_BASE + 0x10000000UL) #define D1_AHB1PERIPH_BASE (PERIPH_BASE + 0x12000000UL) #define D3_APB1PERIPH_BASE (PERIPH_BASE + 0x18000000UL) #define D3_AHB1PERIPH_BASE (PERIPH_BASE + 0x18020000UL) /*!< Legacy Peripheral memory map */ #define APB1PERIPH_BASE PERIPH_BASE #define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000UL) #define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000UL) #define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000UL) /*!< D1_AHB1PERIPH peripherals */ #define MDMA_BASE (D1_AHB1PERIPH_BASE + 0x0000UL) #define DMA2D_BASE (D1_AHB1PERIPH_BASE + 0x1000UL) #define JPGDEC_BASE (D1_AHB1PERIPH_BASE + 0x3000UL) #define FLASH_R_BASE (D1_AHB1PERIPH_BASE + 0x2000UL) #define FMC_R_BASE (D1_AHB1PERIPH_BASE + 0x4000UL) #define QSPI_R_BASE (D1_AHB1PERIPH_BASE + 0x5000UL) #define DLYB_QSPI_BASE (D1_AHB1PERIPH_BASE + 0x6000UL) #define SDMMC1_BASE (D1_AHB1PERIPH_BASE + 0x7000UL) #define DLYB_SDMMC1_BASE (D1_AHB1PERIPH_BASE + 0x8000UL) #define RAMECC1_BASE (D1_AHB1PERIPH_BASE + 0x9000UL) /*!< D2_AHB1PERIPH peripherals */ #define DMA1_BASE (D2_AHB1PERIPH_BASE + 0x0000UL) #define DMA2_BASE (D2_AHB1PERIPH_BASE + 0x0400UL) #define DMAMUX1_BASE (D2_AHB1PERIPH_BASE + 0x0800UL) #define ADC1_BASE (D2_AHB1PERIPH_BASE + 0x2000UL) #define ADC2_BASE (D2_AHB1PERIPH_BASE + 0x2100UL) #define ADC12_COMMON_BASE (D2_AHB1PERIPH_BASE + 0x2300UL) #define ETH_BASE (D2_AHB1PERIPH_BASE + 0x8000UL) #define ETH_MAC_BASE (ETH_BASE) /*!< USB registers base address */ #define USB1_OTG_HS_PERIPH_BASE (0x40040000UL) #define USB2_OTG_FS_PERIPH_BASE (0x40080000UL) #define USB_OTG_GLOBAL_BASE (0x000UL) #define USB_OTG_DEVICE_BASE (0x800UL) #define USB_OTG_IN_ENDPOINT_BASE (0x900UL) #define USB_OTG_OUT_ENDPOINT_BASE (0xB00UL) #define USB_OTG_EP_REG_SIZE (0x20UL) #define USB_OTG_HOST_BASE (0x400UL) #define USB_OTG_HOST_PORT_BASE (0x440UL) #define USB_OTG_HOST_CHANNEL_BASE (0x500UL) #define USB_OTG_HOST_CHANNEL_SIZE (0x20UL) #define USB_OTG_PCGCCTL_BASE (0xE00UL) #define USB_OTG_FIFO_BASE (0x1000UL) #define USB_OTG_FIFO_SIZE (0x1000UL) /*!< D2_AHB2PERIPH peripherals */ #define DCMI_BASE (D2_AHB2PERIPH_BASE + 0x0000UL) #define RNG_BASE (D2_AHB2PERIPH_BASE + 0x1800UL) #define SDMMC2_BASE (D2_AHB2PERIPH_BASE + 0x2400UL) #define DLYB_SDMMC2_BASE (D2_AHB2PERIPH_BASE + 0x2800UL) #define RAMECC2_BASE (D2_AHB2PERIPH_BASE + 0x3000UL) /*!< D3_AHB1PERIPH peripherals */ #define GPIOA_BASE (D3_AHB1PERIPH_BASE + 0x0000UL) #define GPIOB_BASE (D3_AHB1PERIPH_BASE + 0x0400UL) #define GPIOC_BASE (D3_AHB1PERIPH_BASE + 0x0800UL) #define GPIOD_BASE (D3_AHB1PERIPH_BASE + 0x0C00UL) #define GPIOE_BASE (D3_AHB1PERIPH_BASE + 0x1000UL) #define GPIOF_BASE (D3_AHB1PERIPH_BASE + 0x1400UL) #define GPIOG_BASE (D3_AHB1PERIPH_BASE + 0x1800UL) #define GPIOH_BASE (D3_AHB1PERIPH_BASE + 0x1C00UL) #define GPIOI_BASE (D3_AHB1PERIPH_BASE + 0x2000UL) #define GPIOJ_BASE (D3_AHB1PERIPH_BASE + 0x2400UL) #define GPIOK_BASE (D3_AHB1PERIPH_BASE + 0x2800UL) #define RCC_BASE (D3_AHB1PERIPH_BASE + 0x4400UL) #define PWR_BASE (D3_AHB1PERIPH_BASE + 0x4800UL) #define CRC_BASE (D3_AHB1PERIPH_BASE + 0x4C00UL) #define BDMA_BASE (D3_AHB1PERIPH_BASE + 0x5400UL) #define DMAMUX2_BASE (D3_AHB1PERIPH_BASE + 0x5800UL) #define ADC3_BASE (D3_AHB1PERIPH_BASE + 0x6000UL) #define ADC3_COMMON_BASE (D3_AHB1PERIPH_BASE + 0x6300UL) #define HSEM_BASE (D3_AHB1PERIPH_BASE + 0x6400UL) #define RAMECC3_BASE (D3_AHB1PERIPH_BASE + 0x7000UL) /*!< D1_APB1PERIPH peripherals */ #define LTDC_BASE (D1_APB1PERIPH_BASE + 0x1000UL) #define LTDC_Layer1_BASE (LTDC_BASE + 0x84UL) #define LTDC_Layer2_BASE (LTDC_BASE + 0x104UL) #define WWDG1_BASE (D1_APB1PERIPH_BASE + 0x3000UL) /*!< D2_APB1PERIPH peripherals */ #define TIM2_BASE (D2_APB1PERIPH_BASE + 0x0000UL) #define TIM3_BASE (D2_APB1PERIPH_BASE + 0x0400UL) #define TIM4_BASE (D2_APB1PERIPH_BASE + 0x0800UL) #define TIM5_BASE (D2_APB1PERIPH_BASE + 0x0C00UL) #define TIM6_BASE (D2_APB1PERIPH_BASE + 0x1000UL) #define TIM7_BASE (D2_APB1PERIPH_BASE + 0x1400UL) #define TIM12_BASE (D2_APB1PERIPH_BASE + 0x1800UL) #define TIM13_BASE (D2_APB1PERIPH_BASE + 0x1C00UL) #define TIM14_BASE (D2_APB1PERIPH_BASE + 0x2000UL) #define LPTIM1_BASE (D2_APB1PERIPH_BASE + 0x2400UL) #define SPI2_BASE (D2_APB1PERIPH_BASE + 0x3800UL) #define SPI3_BASE (D2_APB1PERIPH_BASE + 0x3C00UL) #define SPDIFRX_BASE (D2_APB1PERIPH_BASE + 0x4000UL) #define USART2_BASE (D2_APB1PERIPH_BASE + 0x4400UL) #define USART3_BASE (D2_APB1PERIPH_BASE + 0x4800UL) #define UART4_BASE (D2_APB1PERIPH_BASE + 0x4C00UL) #define UART5_BASE (D2_APB1PERIPH_BASE + 0x5000UL) #define I2C1_BASE (D2_APB1PERIPH_BASE + 0x5400UL) #define I2C2_BASE (D2_APB1PERIPH_BASE + 0x5800UL) #define I2C3_BASE (D2_APB1PERIPH_BASE + 0x5C00UL) #define CEC_BASE (D2_APB1PERIPH_BASE + 0x6C00UL) #define DAC1_BASE (D2_APB1PERIPH_BASE + 0x7400UL) #define UART7_BASE (D2_APB1PERIPH_BASE + 0x7800UL) #define UART8_BASE (D2_APB1PERIPH_BASE + 0x7C00UL) #define CRS_BASE (D2_APB1PERIPH_BASE + 0x8400UL) #define SWPMI1_BASE (D2_APB1PERIPH_BASE + 0x8800UL) #define OPAMP_BASE (D2_APB1PERIPH_BASE + 0x9000UL) #define OPAMP1_BASE (D2_APB1PERIPH_BASE + 0x9000UL) #define OPAMP2_BASE (D2_APB1PERIPH_BASE + 0x9010UL) #define MDIOS_BASE (D2_APB1PERIPH_BASE + 0x9400UL) #define FDCAN1_BASE (D2_APB1PERIPH_BASE + 0xA000UL) #define FDCAN2_BASE (D2_APB1PERIPH_BASE + 0xA400UL) #define FDCAN_CCU_BASE (D2_APB1PERIPH_BASE + 0xA800UL) #define SRAMCAN_BASE (D2_APB1PERIPH_BASE + 0xAC00UL) /*!< D2_APB2PERIPH peripherals */ #define TIM1_BASE (D2_APB2PERIPH_BASE + 0x0000UL) #define TIM8_BASE (D2_APB2PERIPH_BASE + 0x0400UL) #define USART1_BASE (D2_APB2PERIPH_BASE + 0x1000UL) #define USART6_BASE (D2_APB2PERIPH_BASE + 0x1400UL) #define SPI1_BASE (D2_APB2PERIPH_BASE + 0x3000UL) #define SPI4_BASE (D2_APB2PERIPH_BASE + 0x3400UL) #define TIM15_BASE (D2_APB2PERIPH_BASE + 0x4000UL) #define TIM16_BASE (D2_APB2PERIPH_BASE + 0x4400UL) #define TIM17_BASE (D2_APB2PERIPH_BASE + 0x4800UL) #define SPI5_BASE (D2_APB2PERIPH_BASE + 0x5000UL) #define SAI1_BASE (D2_APB2PERIPH_BASE + 0x5800UL) #define SAI1_Block_A_BASE (SAI1_BASE + 0x004UL) #define SAI1_Block_B_BASE (SAI1_BASE + 0x024UL) #define SAI2_BASE (D2_APB2PERIPH_BASE + 0x5C00UL) #define SAI2_Block_A_BASE (SAI2_BASE + 0x004UL) #define SAI2_Block_B_BASE (SAI2_BASE + 0x024UL) #define SAI3_BASE (D2_APB2PERIPH_BASE + 0x6000UL) #define SAI3_Block_A_BASE (SAI3_BASE + 0x004UL) #define SAI3_Block_B_BASE (SAI3_BASE + 0x024UL) #define DFSDM1_BASE (D2_APB2PERIPH_BASE + 0x7000UL) #define DFSDM1_Channel0_BASE (DFSDM1_BASE + 0x00UL) #define DFSDM1_Channel1_BASE (DFSDM1_BASE + 0x20UL) #define DFSDM1_Channel2_BASE (DFSDM1_BASE + 0x40UL) #define DFSDM1_Channel3_BASE (DFSDM1_BASE + 0x60UL) #define DFSDM1_Channel4_BASE (DFSDM1_BASE + 0x80UL) #define DFSDM1_Channel5_BASE (DFSDM1_BASE + 0xA0UL) #define DFSDM1_Channel6_BASE (DFSDM1_BASE + 0xC0UL) #define DFSDM1_Channel7_BASE (DFSDM1_BASE + 0xE0UL) #define DFSDM1_Filter0_BASE (DFSDM1_BASE + 0x100UL) #define DFSDM1_Filter1_BASE (DFSDM1_BASE + 0x180UL) #define DFSDM1_Filter2_BASE (DFSDM1_BASE + 0x200UL) #define DFSDM1_Filter3_BASE (DFSDM1_BASE + 0x280UL) #define HRTIM1_BASE (D2_APB2PERIPH_BASE + 0x7400UL) #define HRTIM1_TIMA_BASE (HRTIM1_BASE + 0x00000080UL) #define HRTIM1_TIMB_BASE (HRTIM1_BASE + 0x00000100UL) #define HRTIM1_TIMC_BASE (HRTIM1_BASE + 0x00000180UL) #define HRTIM1_TIMD_BASE (HRTIM1_BASE + 0x00000200UL) #define HRTIM1_TIME_BASE (HRTIM1_BASE + 0x00000280UL) #define HRTIM1_COMMON_BASE (HRTIM1_BASE + 0x00000380UL) /*!< D3_APB1PERIPH peripherals */ #define EXTI_BASE (D3_APB1PERIPH_BASE + 0x0000UL) #define EXTI_D1_BASE (EXTI_BASE + 0x0080UL) #define EXTI_D2_BASE (EXTI_BASE + 0x00C0UL) #define SYSCFG_BASE (D3_APB1PERIPH_BASE + 0x0400UL) #define LPUART1_BASE (D3_APB1PERIPH_BASE + 0x0C00UL) #define SPI6_BASE (D3_APB1PERIPH_BASE + 0x1400UL) #define I2C4_BASE (D3_APB1PERIPH_BASE + 0x1C00UL) #define LPTIM2_BASE (D3_APB1PERIPH_BASE + 0x2400UL) #define LPTIM3_BASE (D3_APB1PERIPH_BASE + 0x2800UL) #define LPTIM4_BASE (D3_APB1PERIPH_BASE + 0x2C00UL) #define LPTIM5_BASE (D3_APB1PERIPH_BASE + 0x3000UL) #define COMP12_BASE (D3_APB1PERIPH_BASE + 0x3800UL) #define COMP1_BASE (COMP12_BASE + 0x0CUL) #define COMP2_BASE (COMP12_BASE + 0x10UL) #define VREFBUF_BASE (D3_APB1PERIPH_BASE + 0x3C00UL) #define RTC_BASE (D3_APB1PERIPH_BASE + 0x4000UL) #define IWDG1_BASE (D3_APB1PERIPH_BASE + 0x4800UL) #define SAI4_BASE (D3_APB1PERIPH_BASE + 0x5400UL) #define SAI4_Block_A_BASE (SAI4_BASE + 0x004UL) #define SAI4_Block_B_BASE (SAI4_BASE + 0x024UL) #define BDMA_Channel0_BASE (BDMA_BASE + 0x0008UL) #define BDMA_Channel1_BASE (BDMA_BASE + 0x001CUL) #define BDMA_Channel2_BASE (BDMA_BASE + 0x0030UL) #define BDMA_Channel3_BASE (BDMA_BASE + 0x0044UL) #define BDMA_Channel4_BASE (BDMA_BASE + 0x0058UL) #define BDMA_Channel5_BASE (BDMA_BASE + 0x006CUL) #define BDMA_Channel6_BASE (BDMA_BASE + 0x0080UL) #define BDMA_Channel7_BASE (BDMA_BASE + 0x0094UL) #define DMAMUX2_Channel0_BASE (DMAMUX2_BASE) #define DMAMUX2_Channel1_BASE (DMAMUX2_BASE + 0x0004UL) #define DMAMUX2_Channel2_BASE (DMAMUX2_BASE + 0x0008UL) #define DMAMUX2_Channel3_BASE (DMAMUX2_BASE + 0x000CUL) #define DMAMUX2_Channel4_BASE (DMAMUX2_BASE + 0x0010UL) #define DMAMUX2_Channel5_BASE (DMAMUX2_BASE + 0x0014UL) #define DMAMUX2_Channel6_BASE (DMAMUX2_BASE + 0x0018UL) #define DMAMUX2_Channel7_BASE (DMAMUX2_BASE + 0x001CUL) #define DMAMUX2_RequestGenerator0_BASE (DMAMUX2_BASE + 0x0100UL) #define DMAMUX2_RequestGenerator1_BASE (DMAMUX2_BASE + 0x0104UL) #define DMAMUX2_RequestGenerator2_BASE (DMAMUX2_BASE + 0x0108UL) #define DMAMUX2_RequestGenerator3_BASE (DMAMUX2_BASE + 0x010CUL) #define DMAMUX2_RequestGenerator4_BASE (DMAMUX2_BASE + 0x0110UL) #define DMAMUX2_RequestGenerator5_BASE (DMAMUX2_BASE + 0x0114UL) #define DMAMUX2_RequestGenerator6_BASE (DMAMUX2_BASE + 0x0118UL) #define DMAMUX2_RequestGenerator7_BASE (DMAMUX2_BASE + 0x011CUL) #define DMAMUX2_ChannelStatus_BASE (DMAMUX2_BASE + 0x0080UL) #define DMAMUX2_RequestGenStatus_BASE (DMAMUX2_BASE + 0x0140UL) #define DMA1_Stream0_BASE (DMA1_BASE + 0x010UL) #define DMA1_Stream1_BASE (DMA1_BASE + 0x028UL) #define DMA1_Stream2_BASE (DMA1_BASE + 0x040UL) #define DMA1_Stream3_BASE (DMA1_BASE + 0x058UL) #define DMA1_Stream4_BASE (DMA1_BASE + 0x070UL) #define DMA1_Stream5_BASE (DMA1_BASE + 0x088UL) #define DMA1_Stream6_BASE (DMA1_BASE + 0x0A0UL) #define DMA1_Stream7_BASE (DMA1_BASE + 0x0B8UL) #define DMA2_Stream0_BASE (DMA2_BASE + 0x010UL) #define DMA2_Stream1_BASE (DMA2_BASE + 0x028UL) #define DMA2_Stream2_BASE (DMA2_BASE + 0x040UL) #define DMA2_Stream3_BASE (DMA2_BASE + 0x058UL) #define DMA2_Stream4_BASE (DMA2_BASE + 0x070UL) #define DMA2_Stream5_BASE (DMA2_BASE + 0x088UL) #define DMA2_Stream6_BASE (DMA2_BASE + 0x0A0UL) #define DMA2_Stream7_BASE (DMA2_BASE + 0x0B8UL) #define DMAMUX1_Channel0_BASE (DMAMUX1_BASE) #define DMAMUX1_Channel1_BASE (DMAMUX1_BASE + 0x0004UL) #define DMAMUX1_Channel2_BASE (DMAMUX1_BASE + 0x0008UL) #define DMAMUX1_Channel3_BASE (DMAMUX1_BASE + 0x000CUL) #define DMAMUX1_Channel4_BASE (DMAMUX1_BASE + 0x0010UL) #define DMAMUX1_Channel5_BASE (DMAMUX1_BASE + 0x0014UL) #define DMAMUX1_Channel6_BASE (DMAMUX1_BASE + 0x0018UL) #define DMAMUX1_Channel7_BASE (DMAMUX1_BASE + 0x001CUL) #define DMAMUX1_Channel8_BASE (DMAMUX1_BASE + 0x0020UL) #define DMAMUX1_Channel9_BASE (DMAMUX1_BASE + 0x0024UL) #define DMAMUX1_Channel10_BASE (DMAMUX1_BASE + 0x0028UL) #define DMAMUX1_Channel11_BASE (DMAMUX1_BASE + 0x002CUL) #define DMAMUX1_Channel12_BASE (DMAMUX1_BASE + 0x0030UL) #define DMAMUX1_Channel13_BASE (DMAMUX1_BASE + 0x0034UL) #define DMAMUX1_Channel14_BASE (DMAMUX1_BASE + 0x0038UL) #define DMAMUX1_Channel15_BASE (DMAMUX1_BASE + 0x003CUL) #define DMAMUX1_RequestGenerator0_BASE (DMAMUX1_BASE + 0x0100UL) #define DMAMUX1_RequestGenerator1_BASE (DMAMUX1_BASE + 0x0104UL) #define DMAMUX1_RequestGenerator2_BASE (DMAMUX1_BASE + 0x0108UL) #define DMAMUX1_RequestGenerator3_BASE (DMAMUX1_BASE + 0x010CUL) #define DMAMUX1_RequestGenerator4_BASE (DMAMUX1_BASE + 0x0110UL) #define DMAMUX1_RequestGenerator5_BASE (DMAMUX1_BASE + 0x0114UL) #define DMAMUX1_RequestGenerator6_BASE (DMAMUX1_BASE + 0x0118UL) #define DMAMUX1_RequestGenerator7_BASE (DMAMUX1_BASE + 0x011CUL) #define DMAMUX1_ChannelStatus_BASE (DMAMUX1_BASE + 0x0080UL) #define DMAMUX1_RequestGenStatus_BASE (DMAMUX1_BASE + 0x0140UL) /*!< FMC Banks registers base address */ #define FMC_Bank1_R_BASE (FMC_R_BASE + 0x0000UL) #define FMC_Bank1E_R_BASE (FMC_R_BASE + 0x0104UL) #define FMC_Bank2_R_BASE (FMC_R_BASE + 0x0060UL) #define FMC_Bank3_R_BASE (FMC_R_BASE + 0x0080UL) #define FMC_Bank5_6_R_BASE (FMC_R_BASE + 0x0140UL) /* Debug MCU registers base address */ #define DBGMCU_BASE (0x5C001000UL) #define MDMA_Channel0_BASE (MDMA_BASE + 0x00000040UL) #define MDMA_Channel1_BASE (MDMA_BASE + 0x00000080UL) #define MDMA_Channel2_BASE (MDMA_BASE + 0x000000C0UL) #define MDMA_Channel3_BASE (MDMA_BASE + 0x00000100UL) #define MDMA_Channel4_BASE (MDMA_BASE + 0x00000140UL) #define MDMA_Channel5_BASE (MDMA_BASE + 0x00000180UL) #define MDMA_Channel6_BASE (MDMA_BASE + 0x000001C0UL) #define MDMA_Channel7_BASE (MDMA_BASE + 0x00000200UL) #define MDMA_Channel8_BASE (MDMA_BASE + 0x00000240UL) #define MDMA_Channel9_BASE (MDMA_BASE + 0x00000280UL) #define MDMA_Channel10_BASE (MDMA_BASE + 0x000002C0UL) #define MDMA_Channel11_BASE (MDMA_BASE + 0x00000300UL) #define MDMA_Channel12_BASE (MDMA_BASE + 0x00000340UL) #define MDMA_Channel13_BASE (MDMA_BASE + 0x00000380UL) #define MDMA_Channel14_BASE (MDMA_BASE + 0x000003C0UL) #define MDMA_Channel15_BASE (MDMA_BASE + 0x00000400UL) #define RAMECC1_Monitor1_BASE (RAMECC1_BASE + 0x20UL) #define RAMECC1_Monitor2_BASE (RAMECC1_BASE + 0x40UL) #define RAMECC1_Monitor3_BASE (RAMECC1_BASE + 0x60UL) #define RAMECC1_Monitor4_BASE (RAMECC1_BASE + 0x80UL) #define RAMECC1_Monitor5_BASE (RAMECC1_BASE + 0xA0UL) #define RAMECC2_Monitor1_BASE (RAMECC2_BASE + 0x20UL) #define RAMECC2_Monitor2_BASE (RAMECC2_BASE + 0x40UL) #define RAMECC2_Monitor3_BASE (RAMECC2_BASE + 0x60UL) #define RAMECC2_Monitor4_BASE (RAMECC2_BASE + 0x80UL) #define RAMECC2_Monitor5_BASE (RAMECC2_BASE + 0xA0UL) #define RAMECC3_Monitor1_BASE (RAMECC3_BASE + 0x20UL) #define RAMECC3_Monitor2_BASE (RAMECC3_BASE + 0x40UL) #define GPV_BASE (PERIPH_BASE + 0x11000000UL) /*!< GPV_BASE (PERIPH_BASE + 0x11000000UL) */ /** * @} */ /** @addtogroup Peripheral_declaration * @{ */ #define TIM2 ((TIM_TypeDef *) TIM2_BASE) #define TIM3 ((TIM_TypeDef *) TIM3_BASE) #define TIM4 ((TIM_TypeDef *) TIM4_BASE) #define TIM5 ((TIM_TypeDef *) TIM5_BASE) #define TIM6 ((TIM_TypeDef *) TIM6_BASE) #define TIM7 ((TIM_TypeDef *) TIM7_BASE) #define TIM13 ((TIM_TypeDef *) TIM13_BASE) #define TIM14 ((TIM_TypeDef *) TIM14_BASE) #define VREFBUF ((VREFBUF_TypeDef *) VREFBUF_BASE) #define RTC ((RTC_TypeDef *) RTC_BASE) #define WWDG1 ((WWDG_TypeDef *) WWDG1_BASE) #define IWDG1 ((IWDG_TypeDef *) IWDG1_BASE) #define SPI2 ((SPI_TypeDef *) SPI2_BASE) #define SPI3 ((SPI_TypeDef *) SPI3_BASE) #define SPI4 ((SPI_TypeDef *) SPI4_BASE) #define SPI5 ((SPI_TypeDef *) SPI5_BASE) #define SPI6 ((SPI_TypeDef *) SPI6_BASE) #define USART2 ((USART_TypeDef *) USART2_BASE) #define USART3 ((USART_TypeDef *) USART3_BASE) #define USART6 ((USART_TypeDef *) USART6_BASE) #define UART7 ((USART_TypeDef *) UART7_BASE) #define UART8 ((USART_TypeDef *) UART8_BASE) #define CRS ((CRS_TypeDef *) CRS_BASE) #define UART4 ((USART_TypeDef *) UART4_BASE) #define UART5 ((USART_TypeDef *) UART5_BASE) #define I2C1 ((I2C_TypeDef *) I2C1_BASE) #define I2C2 ((I2C_TypeDef *) I2C2_BASE) #define I2C3 ((I2C_TypeDef *) I2C3_BASE) #define I2C4 ((I2C_TypeDef *) I2C4_BASE) #define FDCAN1 ((FDCAN_GlobalTypeDef *) FDCAN1_BASE) #define FDCAN2 ((FDCAN_GlobalTypeDef *) FDCAN2_BASE) #define FDCAN_CCU ((FDCAN_ClockCalibrationUnit_TypeDef *) FDCAN_CCU_BASE) #define CEC ((CEC_TypeDef *) CEC_BASE) #define LPTIM1 ((LPTIM_TypeDef *) LPTIM1_BASE) #define PWR ((PWR_TypeDef *) PWR_BASE) #define DAC1 ((DAC_TypeDef *) DAC1_BASE) #define LPUART1 ((USART_TypeDef *) LPUART1_BASE) #define SWPMI1 ((SWPMI_TypeDef *) SWPMI1_BASE) #define LPTIM2 ((LPTIM_TypeDef *) LPTIM2_BASE) #define LPTIM3 ((LPTIM_TypeDef *) LPTIM3_BASE) #define LPTIM4 ((LPTIM_TypeDef *) LPTIM4_BASE) #define LPTIM5 ((LPTIM_TypeDef *) LPTIM5_BASE) #define SYSCFG ((SYSCFG_TypeDef *) SYSCFG_BASE) #define COMP12 ((COMPOPT_TypeDef *) COMP12_BASE) #define COMP1 ((COMP_TypeDef *) COMP1_BASE) #define COMP2 ((COMP_TypeDef *) COMP2_BASE) #define COMP12_COMMON ((COMP_Common_TypeDef *) COMP2_BASE) #define OPAMP ((OPAMP_TypeDef *) OPAMP_BASE) #define OPAMP1 ((OPAMP_TypeDef *) OPAMP1_BASE) #define OPAMP2 ((OPAMP_TypeDef *) OPAMP2_BASE) #define EXTI ((EXTI_TypeDef *) EXTI_BASE) #define EXTI_D1 ((EXTI_Core_TypeDef *) EXTI_D1_BASE) #define EXTI_D2 ((EXTI_Core_TypeDef *) EXTI_D2_BASE) #define TIM1 ((TIM_TypeDef *) TIM1_BASE) #define SPI1 ((SPI_TypeDef *) SPI1_BASE) #define TIM8 ((TIM_TypeDef *) TIM8_BASE) #define USART1 ((USART_TypeDef *) USART1_BASE) #define TIM12 ((TIM_TypeDef *) TIM12_BASE) #define TIM15 ((TIM_TypeDef *) TIM15_BASE) #define TIM16 ((TIM_TypeDef *) TIM16_BASE) #define TIM17 ((TIM_TypeDef *) TIM17_BASE) #define HRTIM1 ((HRTIM_TypeDef *) HRTIM1_BASE) #define HRTIM1_TIMA ((HRTIM_Timerx_TypeDef *) HRTIM1_TIMA_BASE) #define HRTIM1_TIMB ((HRTIM_Timerx_TypeDef *) HRTIM1_TIMB_BASE) #define HRTIM1_TIMC ((HRTIM_Timerx_TypeDef *) HRTIM1_TIMC_BASE) #define HRTIM1_TIMD ((HRTIM_Timerx_TypeDef *) HRTIM1_TIMD_BASE) #define HRTIM1_TIME ((HRTIM_Timerx_TypeDef *) HRTIM1_TIME_BASE) #define HRTIM1_COMMON ((HRTIM_Common_TypeDef *) HRTIM1_COMMON_BASE) #define SAI1 ((SAI_TypeDef *) SAI1_BASE) #define SAI1_Block_A ((SAI_Block_TypeDef *)SAI1_Block_A_BASE) #define SAI1_Block_B ((SAI_Block_TypeDef *)SAI1_Block_B_BASE) #define SAI2 ((SAI_TypeDef *) SAI2_BASE) #define SAI2_Block_A ((SAI_Block_TypeDef *)SAI2_Block_A_BASE) #define SAI2_Block_B ((SAI_Block_TypeDef *)SAI2_Block_B_BASE) #define SAI3 ((SAI_TypeDef *) SAI3_BASE) #define SAI3_Block_A ((SAI_Block_TypeDef *)SAI3_Block_A_BASE) #define SAI3_Block_B ((SAI_Block_TypeDef *)SAI3_Block_B_BASE) #define SAI4 ((SAI_TypeDef *) SAI4_BASE) #define SAI4_Block_A ((SAI_Block_TypeDef *)SAI4_Block_A_BASE) #define SAI4_Block_B ((SAI_Block_TypeDef *)SAI4_Block_B_BASE) #define SPDIFRX ((SPDIFRX_TypeDef *) SPDIFRX_BASE) #define DFSDM1_Channel0 ((DFSDM_Channel_TypeDef *) DFSDM1_Channel0_BASE) #define DFSDM1_Channel1 ((DFSDM_Channel_TypeDef *) DFSDM1_Channel1_BASE) #define DFSDM1_Channel2 ((DFSDM_Channel_TypeDef *) DFSDM1_Channel2_BASE) #define DFSDM1_Channel3 ((DFSDM_Channel_TypeDef *) DFSDM1_Channel3_BASE) #define DFSDM1_Channel4 ((DFSDM_Channel_TypeDef *) DFSDM1_Channel4_BASE) #define DFSDM1_Channel5 ((DFSDM_Channel_TypeDef *) DFSDM1_Channel5_BASE) #define DFSDM1_Channel6 ((DFSDM_Channel_TypeDef *) DFSDM1_Channel6_BASE) #define DFSDM1_Channel7 ((DFSDM_Channel_TypeDef *) DFSDM1_Channel7_BASE) #define DFSDM1_Filter0 ((DFSDM_Filter_TypeDef *) DFSDM1_Filter0_BASE) #define DFSDM1_Filter1 ((DFSDM_Filter_TypeDef *) DFSDM1_Filter1_BASE) #define DFSDM1_Filter2 ((DFSDM_Filter_TypeDef *) DFSDM1_Filter2_BASE) #define DFSDM1_Filter3 ((DFSDM_Filter_TypeDef *) DFSDM1_Filter3_BASE) #define DMA2D ((DMA2D_TypeDef *) DMA2D_BASE) #define DCMI ((DCMI_TypeDef *) DCMI_BASE) #define RCC ((RCC_TypeDef *) RCC_BASE) #define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) #define CRC ((CRC_TypeDef *) CRC_BASE) #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) #define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) #define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) #define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) #define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) #define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) #define GPIOG ((GPIO_TypeDef *) GPIOG_BASE) #define GPIOH ((GPIO_TypeDef *) GPIOH_BASE) #define GPIOI ((GPIO_TypeDef *) GPIOI_BASE) #define GPIOJ ((GPIO_TypeDef *) GPIOJ_BASE) #define GPIOK ((GPIO_TypeDef *) GPIOK_BASE) #define ADC1 ((ADC_TypeDef *) ADC1_BASE) #define ADC2 ((ADC_TypeDef *) ADC2_BASE) #define ADC3 ((ADC_TypeDef *) ADC3_BASE) #define ADC3_COMMON ((ADC_Common_TypeDef *) ADC3_COMMON_BASE) #define ADC12_COMMON ((ADC_Common_TypeDef *) ADC12_COMMON_BASE) #define RNG ((RNG_TypeDef *) RNG_BASE) #define SDMMC2 ((SDMMC_TypeDef *) SDMMC2_BASE) #define DLYB_SDMMC2 ((DLYB_TypeDef *) DLYB_SDMMC2_BASE) #define BDMA ((BDMA_TypeDef *) BDMA_BASE) #define BDMA_Channel0 ((BDMA_Channel_TypeDef *) BDMA_Channel0_BASE) #define BDMA_Channel1 ((BDMA_Channel_TypeDef *) BDMA_Channel1_BASE) #define BDMA_Channel2 ((BDMA_Channel_TypeDef *) BDMA_Channel2_BASE) #define BDMA_Channel3 ((BDMA_Channel_TypeDef *) BDMA_Channel3_BASE) #define BDMA_Channel4 ((BDMA_Channel_TypeDef *) BDMA_Channel4_BASE) #define BDMA_Channel5 ((BDMA_Channel_TypeDef *) BDMA_Channel5_BASE) #define BDMA_Channel6 ((BDMA_Channel_TypeDef *) BDMA_Channel6_BASE) #define BDMA_Channel7 ((BDMA_Channel_TypeDef *) BDMA_Channel7_BASE) #define RAMECC1 ((RAMECC_TypeDef *)RAMECC1_BASE) #define RAMECC1_Monitor1 ((RAMECC_MonitorTypeDef *)RAMECC1_Monitor1_BASE) #define RAMECC1_Monitor2 ((RAMECC_MonitorTypeDef *)RAMECC1_Monitor2_BASE) #define RAMECC1_Monitor3 ((RAMECC_MonitorTypeDef *)RAMECC1_Monitor3_BASE) #define RAMECC1_Monitor4 ((RAMECC_MonitorTypeDef *)RAMECC1_Monitor4_BASE) #define RAMECC1_Monitor5 ((RAMECC_MonitorTypeDef *)RAMECC1_Monitor5_BASE) #define RAMECC2 ((RAMECC_TypeDef *)RAMECC2_BASE) #define RAMECC2_Monitor1 ((RAMECC_MonitorTypeDef *)RAMECC2_Monitor1_BASE) #define RAMECC2_Monitor2 ((RAMECC_MonitorTypeDef *)RAMECC2_Monitor2_BASE) #define RAMECC2_Monitor3 ((RAMECC_MonitorTypeDef *)RAMECC2_Monitor3_BASE) #define RAMECC2_Monitor4 ((RAMECC_MonitorTypeDef *)RAMECC2_Monitor4_BASE) #define RAMECC2_Monitor5 ((RAMECC_MonitorTypeDef *)RAMECC2_Monitor5_BASE) #define RAMECC3 ((RAMECC_TypeDef *)RAMECC3_BASE) #define RAMECC3_Monitor1 ((RAMECC_MonitorTypeDef *)RAMECC3_Monitor1_BASE) #define RAMECC3_Monitor2 ((RAMECC_MonitorTypeDef *)RAMECC3_Monitor2_BASE) #define DMAMUX2 ((DMAMUX_Channel_TypeDef *) DMAMUX2_BASE) #define DMAMUX2_Channel0 ((DMAMUX_Channel_TypeDef *) DMAMUX2_Channel0_BASE) #define DMAMUX2_Channel1 ((DMAMUX_Channel_TypeDef *) DMAMUX2_Channel1_BASE) #define DMAMUX2_Channel2 ((DMAMUX_Channel_TypeDef *) DMAMUX2_Channel2_BASE) #define DMAMUX2_Channel3 ((DMAMUX_Channel_TypeDef *) DMAMUX2_Channel3_BASE) #define DMAMUX2_Channel4 ((DMAMUX_Channel_TypeDef *) DMAMUX2_Channel4_BASE) #define DMAMUX2_Channel5 ((DMAMUX_Channel_TypeDef *) DMAMUX2_Channel5_BASE) #define DMAMUX2_Channel6 ((DMAMUX_Channel_TypeDef *) DMAMUX2_Channel6_BASE) #define DMAMUX2_Channel7 ((DMAMUX_Channel_TypeDef *) DMAMUX2_Channel7_BASE) #define DMAMUX2_RequestGenerator0 ((DMAMUX_RequestGen_TypeDef *) DMAMUX2_RequestGenerator0_BASE) #define DMAMUX2_RequestGenerator1 ((DMAMUX_RequestGen_TypeDef *) DMAMUX2_RequestGenerator1_BASE) #define DMAMUX2_RequestGenerator2 ((DMAMUX_RequestGen_TypeDef *) DMAMUX2_RequestGenerator2_BASE) #define DMAMUX2_RequestGenerator3 ((DMAMUX_RequestGen_TypeDef *) DMAMUX2_RequestGenerator3_BASE) #define DMAMUX2_RequestGenerator4 ((DMAMUX_RequestGen_TypeDef *) DMAMUX2_RequestGenerator4_BASE) #define DMAMUX2_RequestGenerator5 ((DMAMUX_RequestGen_TypeDef *) DMAMUX2_RequestGenerator5_BASE) #define DMAMUX2_RequestGenerator6 ((DMAMUX_RequestGen_TypeDef *) DMAMUX2_RequestGenerator6_BASE) #define DMAMUX2_RequestGenerator7 ((DMAMUX_RequestGen_TypeDef *) DMAMUX2_RequestGenerator7_BASE) #define DMAMUX2_ChannelStatus ((DMAMUX_ChannelStatus_TypeDef *) DMAMUX2_ChannelStatus_BASE) #define DMAMUX2_RequestGenStatus ((DMAMUX_RequestGenStatus_TypeDef *) DMAMUX2_RequestGenStatus_BASE) #define DMA2 ((DMA_TypeDef *) DMA2_BASE) #define DMA2_Stream0 ((DMA_Stream_TypeDef *) DMA2_Stream0_BASE) #define DMA2_Stream1 ((DMA_Stream_TypeDef *) DMA2_Stream1_BASE) #define DMA2_Stream2 ((DMA_Stream_TypeDef *) DMA2_Stream2_BASE) #define DMA2_Stream3 ((DMA_Stream_TypeDef *) DMA2_Stream3_BASE) #define DMA2_Stream4 ((DMA_Stream_TypeDef *) DMA2_Stream4_BASE) #define DMA2_Stream5 ((DMA_Stream_TypeDef *) DMA2_Stream5_BASE) #define DMA2_Stream6 ((DMA_Stream_TypeDef *) DMA2_Stream6_BASE) #define DMA2_Stream7 ((DMA_Stream_TypeDef *) DMA2_Stream7_BASE) #define DMA1 ((DMA_TypeDef *) DMA1_BASE) #define DMA1_Stream0 ((DMA_Stream_TypeDef *) DMA1_Stream0_BASE) #define DMA1_Stream1 ((DMA_Stream_TypeDef *) DMA1_Stream1_BASE) #define DMA1_Stream2 ((DMA_Stream_TypeDef *) DMA1_Stream2_BASE) #define DMA1_Stream3 ((DMA_Stream_TypeDef *) DMA1_Stream3_BASE) #define DMA1_Stream4 ((DMA_Stream_TypeDef *) DMA1_Stream4_BASE) #define DMA1_Stream5 ((DMA_Stream_TypeDef *) DMA1_Stream5_BASE) #define DMA1_Stream6 ((DMA_Stream_TypeDef *) DMA1_Stream6_BASE) #define DMA1_Stream7 ((DMA_Stream_TypeDef *) DMA1_Stream7_BASE) #define DMAMUX1 ((DMAMUX_Channel_TypeDef *) DMAMUX1_BASE) #define DMAMUX1_Channel0 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel0_BASE) #define DMAMUX1_Channel1 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel1_BASE) #define DMAMUX1_Channel2 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel2_BASE) #define DMAMUX1_Channel3 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel3_BASE) #define DMAMUX1_Channel4 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel4_BASE) #define DMAMUX1_Channel5 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel5_BASE) #define DMAMUX1_Channel6 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel6_BASE) #define DMAMUX1_Channel7 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel7_BASE) #define DMAMUX1_Channel8 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel8_BASE) #define DMAMUX1_Channel9 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel9_BASE) #define DMAMUX1_Channel10 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel10_BASE) #define DMAMUX1_Channel11 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel11_BASE) #define DMAMUX1_Channel12 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel12_BASE) #define DMAMUX1_Channel13 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel13_BASE) #define DMAMUX1_Channel14 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel14_BASE) #define DMAMUX1_Channel15 ((DMAMUX_Channel_TypeDef *) DMAMUX1_Channel15_BASE) #define DMAMUX1_RequestGenerator0 ((DMAMUX_RequestGen_TypeDef *) DMAMUX1_RequestGenerator0_BASE) #define DMAMUX1_RequestGenerator1 ((DMAMUX_RequestGen_TypeDef *) DMAMUX1_RequestGenerator1_BASE) #define DMAMUX1_RequestGenerator2 ((DMAMUX_RequestGen_TypeDef *) DMAMUX1_RequestGenerator2_BASE) #define DMAMUX1_RequestGenerator3 ((DMAMUX_RequestGen_TypeDef *) DMAMUX1_RequestGenerator3_BASE) #define DMAMUX1_RequestGenerator4 ((DMAMUX_RequestGen_TypeDef *) DMAMUX1_RequestGenerator4_BASE) #define DMAMUX1_RequestGenerator5 ((DMAMUX_RequestGen_TypeDef *) DMAMUX1_RequestGenerator5_BASE) #define DMAMUX1_RequestGenerator6 ((DMAMUX_RequestGen_TypeDef *) DMAMUX1_RequestGenerator6_BASE) #define DMAMUX1_RequestGenerator7 ((DMAMUX_RequestGen_TypeDef *) DMAMUX1_RequestGenerator7_BASE) #define DMAMUX1_ChannelStatus ((DMAMUX_ChannelStatus_TypeDef *) DMAMUX1_ChannelStatus_BASE) #define DMAMUX1_RequestGenStatus ((DMAMUX_RequestGenStatus_TypeDef *) DMAMUX1_RequestGenStatus_BASE) #define FMC_Bank1_R ((FMC_Bank1_TypeDef *) FMC_Bank1_R_BASE) #define FMC_Bank1E_R ((FMC_Bank1E_TypeDef *) FMC_Bank1E_R_BASE) #define FMC_Bank2_R ((FMC_Bank2_TypeDef *) FMC_Bank2_R_BASE) #define FMC_Bank3_R ((FMC_Bank3_TypeDef *) FMC_Bank3_R_BASE) #define FMC_Bank5_6_R ((FMC_Bank5_6_TypeDef *) FMC_Bank5_6_R_BASE) #define QUADSPI ((QUADSPI_TypeDef *) QSPI_R_BASE) #define DLYB_QUADSPI ((DLYB_TypeDef *) DLYB_QSPI_BASE) #define SDMMC1 ((SDMMC_TypeDef *) SDMMC1_BASE) #define DLYB_SDMMC1 ((DLYB_TypeDef *) DLYB_SDMMC1_BASE) #define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) #define JPEG ((JPEG_TypeDef *) JPGDEC_BASE) #define HSEM ((HSEM_TypeDef *) HSEM_BASE) #define HSEM_COMMON ((HSEM_Common_TypeDef *) (HSEM_BASE + 0x100UL)) #define LTDC ((LTDC_TypeDef *)LTDC_BASE) #define LTDC_Layer1 ((LTDC_Layer_TypeDef *)LTDC_Layer1_BASE) #define LTDC_Layer2 ((LTDC_Layer_TypeDef *)LTDC_Layer2_BASE) #define MDIOS ((MDIOS_TypeDef *) MDIOS_BASE) #define ETH ((ETH_TypeDef *)ETH_BASE) #define MDMA ((MDMA_TypeDef *)MDMA_BASE) #define MDMA_Channel0 ((MDMA_Channel_TypeDef *)MDMA_Channel0_BASE) #define MDMA_Channel1 ((MDMA_Channel_TypeDef *)MDMA_Channel1_BASE) #define MDMA_Channel2 ((MDMA_Channel_TypeDef *)MDMA_Channel2_BASE) #define MDMA_Channel3 ((MDMA_Channel_TypeDef *)MDMA_Channel3_BASE) #define MDMA_Channel4 ((MDMA_Channel_TypeDef *)MDMA_Channel4_BASE) #define MDMA_Channel5 ((MDMA_Channel_TypeDef *)MDMA_Channel5_BASE) #define MDMA_Channel6 ((MDMA_Channel_TypeDef *)MDMA_Channel6_BASE) #define MDMA_Channel7 ((MDMA_Channel_TypeDef *)MDMA_Channel7_BASE) #define MDMA_Channel8 ((MDMA_Channel_TypeDef *)MDMA_Channel8_BASE) #define MDMA_Channel9 ((MDMA_Channel_TypeDef *)MDMA_Channel9_BASE) #define MDMA_Channel10 ((MDMA_Channel_TypeDef *)MDMA_Channel10_BASE) #define MDMA_Channel11 ((MDMA_Channel_TypeDef *)MDMA_Channel11_BASE) #define MDMA_Channel12 ((MDMA_Channel_TypeDef *)MDMA_Channel12_BASE) #define MDMA_Channel13 ((MDMA_Channel_TypeDef *)MDMA_Channel13_BASE) #define MDMA_Channel14 ((MDMA_Channel_TypeDef *)MDMA_Channel14_BASE) #define MDMA_Channel15 ((MDMA_Channel_TypeDef *)MDMA_Channel15_BASE) #define USB1_OTG_HS ((USB_OTG_GlobalTypeDef *) USB1_OTG_HS_PERIPH_BASE) #define USB2_OTG_FS ((USB_OTG_GlobalTypeDef *) USB2_OTG_FS_PERIPH_BASE) /* Legacy defines */ #define USB_OTG_HS USB1_OTG_HS #define USB_OTG_HS_PERIPH_BASE USB1_OTG_HS_PERIPH_BASE #define USB_OTG_FS USB2_OTG_FS #define USB_OTG_FS_PERIPH_BASE USB2_OTG_FS_PERIPH_BASE #define GPV ((GPV_TypeDef *) GPV_BASE) /** * @} */ /** @addtogroup Exported_constants * @{ */ /** @addtogroup Hardware_Constant_Definition * @{ */ #define LSI_STARTUP_TIME 130U /*!< LSI Maximum startup time in us */ /** * @} */ /** @addtogroup Peripheral_Registers_Bits_Definition * @{ */ /******************************************************************************/ /* Peripheral Registers_Bits_Definition */ /******************************************************************************/ /******************************************************************************/ /* */ /* Analog to Digital Converter */ /* */ /******************************************************************************/ /******************************* ADC VERSION ********************************/ #define ADC_VER_V5_X /******************** Bit definition for ADC_ISR register ********************/ #define ADC_ISR_ADRDY_Pos (0U) #define ADC_ISR_ADRDY_Msk (0x1UL << ADC_ISR_ADRDY_Pos) /*!< 0x00000001 */ #define ADC_ISR_ADRDY ADC_ISR_ADRDY_Msk /*!< ADC Ready (ADRDY) flag */ #define ADC_ISR_EOSMP_Pos (1U) #define ADC_ISR_EOSMP_Msk (0x1UL << ADC_ISR_EOSMP_Pos) /*!< 0x00000002 */ #define ADC_ISR_EOSMP ADC_ISR_EOSMP_Msk /*!< ADC End of Sampling flag */ #define ADC_ISR_EOC_Pos (2U) #define ADC_ISR_EOC_Msk (0x1UL << ADC_ISR_EOC_Pos) /*!< 0x00000004 */ #define ADC_ISR_EOC ADC_ISR_EOC_Msk /*!< ADC End of Regular Conversion flag */ #define ADC_ISR_EOS_Pos (3U) #define ADC_ISR_EOS_Msk (0x1UL << ADC_ISR_EOS_Pos) /*!< 0x00000008 */ #define ADC_ISR_EOS ADC_ISR_EOS_Msk /*!< ADC End of Regular sequence of Conversions flag */ #define ADC_ISR_OVR_Pos (4U) #define ADC_ISR_OVR_Msk (0x1UL << ADC_ISR_OVR_Pos) /*!< 0x00000010 */ #define ADC_ISR_OVR ADC_ISR_OVR_Msk /*!< ADC overrun flag */ #define ADC_ISR_JEOC_Pos (5U) #define ADC_ISR_JEOC_Msk (0x1UL << ADC_ISR_JEOC_Pos) /*!< 0x00000020 */ #define ADC_ISR_JEOC ADC_ISR_JEOC_Msk /*!< ADC End of Injected Conversion flag */ #define ADC_ISR_JEOS_Pos (6U) #define ADC_ISR_JEOS_Msk (0x1UL << ADC_ISR_JEOS_Pos) /*!< 0x00000040 */ #define ADC_ISR_JEOS ADC_ISR_JEOS_Msk /*!< ADC End of Injected sequence of Conversions flag */ #define ADC_ISR_AWD1_Pos (7U) #define ADC_ISR_AWD1_Msk (0x1UL << ADC_ISR_AWD1_Pos) /*!< 0x00000080 */ #define ADC_ISR_AWD1 ADC_ISR_AWD1_Msk /*!< ADC Analog watchdog 1 flag */ #define ADC_ISR_AWD2_Pos (8U) #define ADC_ISR_AWD2_Msk (0x1UL << ADC_ISR_AWD2_Pos) /*!< 0x00000100 */ #define ADC_ISR_AWD2 ADC_ISR_AWD2_Msk /*!< ADC Analog watchdog 2 flag */ #define ADC_ISR_AWD3_Pos (9U) #define ADC_ISR_AWD3_Msk (0x1UL << ADC_ISR_AWD3_Pos) /*!< 0x00000200 */ #define ADC_ISR_AWD3 ADC_ISR_AWD3_Msk /*!< ADC Analog watchdog 3 flag */ #define ADC_ISR_JQOVF_Pos (10U) #define ADC_ISR_JQOVF_Msk (0x1UL << ADC_ISR_JQOVF_Pos) /*!< 0x00000400 */ #define ADC_ISR_JQOVF ADC_ISR_JQOVF_Msk /*!< ADC Injected Context Queue Overflow flag */ /******************** Bit definition for ADC_IER register ********************/ #define ADC_IER_ADRDYIE_Pos (0U) #define ADC_IER_ADRDYIE_Msk (0x1UL << ADC_IER_ADRDYIE_Pos) /*!< 0x00000001 */ #define ADC_IER_ADRDYIE ADC_IER_ADRDYIE_Msk /*!< ADC Ready (ADRDY) interrupt source */ #define ADC_IER_EOSMPIE_Pos (1U) #define ADC_IER_EOSMPIE_Msk (0x1UL << ADC_IER_EOSMPIE_Pos) /*!< 0x00000002 */ #define ADC_IER_EOSMPIE ADC_IER_EOSMPIE_Msk /*!< ADC End of Sampling interrupt source */ #define ADC_IER_EOCIE_Pos (2U) #define ADC_IER_EOCIE_Msk (0x1UL << ADC_IER_EOCIE_Pos) /*!< 0x00000004 */ #define ADC_IER_EOCIE ADC_IER_EOCIE_Msk /*!< ADC End of Regular Conversion interrupt source */ #define ADC_IER_EOSIE_Pos (3U) #define ADC_IER_EOSIE_Msk (0x1UL << ADC_IER_EOSIE_Pos) /*!< 0x00000008 */ #define ADC_IER_EOSIE ADC_IER_EOSIE_Msk /*!< ADC End of Regular sequence of Conversions interrupt source */ #define ADC_IER_OVRIE_Pos (4U) #define ADC_IER_OVRIE_Msk (0x1UL << ADC_IER_OVRIE_Pos) /*!< 0x00000010 */ #define ADC_IER_OVRIE ADC_IER_OVRIE_Msk /*!< ADC overrun interrupt source */ #define ADC_IER_JEOCIE_Pos (5U) #define ADC_IER_JEOCIE_Msk (0x1UL << ADC_IER_JEOCIE_Pos) /*!< 0x00000020 */ #define ADC_IER_JEOCIE ADC_IER_JEOCIE_Msk /*!< ADC End of Injected Conversion interrupt source */ #define ADC_IER_JEOSIE_Pos (6U) #define ADC_IER_JEOSIE_Msk (0x1UL << ADC_IER_JEOSIE_Pos) /*!< 0x00000040 */ #define ADC_IER_JEOSIE ADC_IER_JEOSIE_Msk /*!< ADC End of Injected sequence of Conversions interrupt source */ #define ADC_IER_AWD1IE_Pos (7U) #define ADC_IER_AWD1IE_Msk (0x1UL << ADC_IER_AWD1IE_Pos) /*!< 0x00000080 */ #define ADC_IER_AWD1IE ADC_IER_AWD1IE_Msk /*!< ADC Analog watchdog 1 interrupt source */ #define ADC_IER_AWD2IE_Pos (8U) #define ADC_IER_AWD2IE_Msk (0x1UL << ADC_IER_AWD2IE_Pos) /*!< 0x00000100 */ #define ADC_IER_AWD2IE ADC_IER_AWD2IE_Msk /*!< ADC Analog watchdog 2 interrupt source */ #define ADC_IER_AWD3IE_Pos (9U) #define ADC_IER_AWD3IE_Msk (0x1UL << ADC_IER_AWD3IE_Pos) /*!< 0x00000200 */ #define ADC_IER_AWD3IE ADC_IER_AWD3IE_Msk /*!< ADC Analog watchdog 3 interrupt source */ #define ADC_IER_JQOVFIE_Pos (10U) #define ADC_IER_JQOVFIE_Msk (0x1UL << ADC_IER_JQOVFIE_Pos) /*!< 0x00000400 */ #define ADC_IER_JQOVFIE ADC_IER_JQOVFIE_Msk /*!< ADC Injected Context Queue Overflow interrupt source */ /******************** Bit definition for ADC_CR register ********************/ #define ADC_CR_ADEN_Pos (0U) #define ADC_CR_ADEN_Msk (0x1UL << ADC_CR_ADEN_Pos) /*!< 0x00000001 */ #define ADC_CR_ADEN ADC_CR_ADEN_Msk /*!< ADC Enable control */ #define ADC_CR_ADDIS_Pos (1U) #define ADC_CR_ADDIS_Msk (0x1UL << ADC_CR_ADDIS_Pos) /*!< 0x00000002 */ #define ADC_CR_ADDIS ADC_CR_ADDIS_Msk /*!< ADC Disable command */ #define ADC_CR_ADSTART_Pos (2U) #define ADC_CR_ADSTART_Msk (0x1UL << ADC_CR_ADSTART_Pos) /*!< 0x00000004 */ #define ADC_CR_ADSTART ADC_CR_ADSTART_Msk /*!< ADC Start of Regular conversion */ #define ADC_CR_JADSTART_Pos (3U) #define ADC_CR_JADSTART_Msk (0x1UL << ADC_CR_JADSTART_Pos) /*!< 0x00000008 */ #define ADC_CR_JADSTART ADC_CR_JADSTART_Msk /*!< ADC Start of injected conversion */ #define ADC_CR_ADSTP_Pos (4U) #define ADC_CR_ADSTP_Msk (0x1UL << ADC_CR_ADSTP_Pos) /*!< 0x00000010 */ #define ADC_CR_ADSTP ADC_CR_ADSTP_Msk /*!< ADC Stop of Regular conversion */ #define ADC_CR_JADSTP_Pos (5U) #define ADC_CR_JADSTP_Msk (0x1UL << ADC_CR_JADSTP_Pos) /*!< 0x00000020 */ #define ADC_CR_JADSTP ADC_CR_JADSTP_Msk /*!< ADC Stop of injected conversion */ #define ADC_CR_BOOST_Pos (8U) #define ADC_CR_BOOST_Msk (0x3UL << ADC_CR_BOOST_Pos) /*!< 0x00000300 */ #define ADC_CR_BOOST ADC_CR_BOOST_Msk /*!< ADC Boost Mode configuration */ #define ADC_CR_BOOST_0 (0x1UL << ADC_CR_BOOST_Pos) /*!< 0x00000100 */ #define ADC_CR_BOOST_1 (0x2UL << ADC_CR_BOOST_Pos) /*!< 0x00000200 */ #define ADC_CR_ADCALLIN_Pos (16U) #define ADC_CR_ADCALLIN_Msk (0x1UL << ADC_CR_ADCALLIN_Pos) /*!< 0x00010000 */ #define ADC_CR_ADCALLIN ADC_CR_ADCALLIN_Msk /*!< ADC Linearity calibration */ #define ADC_CR_LINCALRDYW1_Pos (22U) #define ADC_CR_LINCALRDYW1_Msk (0x1UL << ADC_CR_LINCALRDYW1_Pos) /*!< 0x00400000 */ #define ADC_CR_LINCALRDYW1 ADC_CR_LINCALRDYW1_Msk /*!< ADC Linearity calibration ready Word 1 */ #define ADC_CR_LINCALRDYW2_Pos (23U) #define ADC_CR_LINCALRDYW2_Msk (0x1UL << ADC_CR_LINCALRDYW2_Pos) /*!< 0x00800000 */ #define ADC_CR_LINCALRDYW2 ADC_CR_LINCALRDYW2_Msk /*!< ADC Linearity calibration ready Word 2 */ #define ADC_CR_LINCALRDYW3_Pos (24U) #define ADC_CR_LINCALRDYW3_Msk (0x1UL << ADC_CR_LINCALRDYW3_Pos) /*!< 0x01000000 */ #define ADC_CR_LINCALRDYW3 ADC_CR_LINCALRDYW3_Msk /*!< ADC Linearity calibration ready Word 3 */ #define ADC_CR_LINCALRDYW4_Pos (25U) #define ADC_CR_LINCALRDYW4_Msk (0x1UL << ADC_CR_LINCALRDYW4_Pos) /*!< 0x02000000 */ #define ADC_CR_LINCALRDYW4 ADC_CR_LINCALRDYW4_Msk /*!< ADC Linearity calibration ready Word 4 */ #define ADC_CR_LINCALRDYW5_Pos (26U) #define ADC_CR_LINCALRDYW5_Msk (0x1UL << ADC_CR_LINCALRDYW5_Pos) /*!< 0x04000000 */ #define ADC_CR_LINCALRDYW5 ADC_CR_LINCALRDYW5_Msk /*!< ADC Linearity calibration ready Word 5 */ #define ADC_CR_LINCALRDYW6_Pos (27U) #define ADC_CR_LINCALRDYW6_Msk (0x1UL << ADC_CR_LINCALRDYW6_Pos) /*!< 0x08000000 */ #define ADC_CR_LINCALRDYW6 ADC_CR_LINCALRDYW6_Msk /*!< ADC Linearity calibration ready Word 6 */ #define ADC_CR_ADVREGEN_Pos (28U) #define ADC_CR_ADVREGEN_Msk (0x1UL << ADC_CR_ADVREGEN_Pos) /*!< 0x10000000 */ #define ADC_CR_ADVREGEN ADC_CR_ADVREGEN_Msk /*!< ADC Voltage regulator Enable */ #define ADC_CR_DEEPPWD_Pos (29U) #define ADC_CR_DEEPPWD_Msk (0x1UL << ADC_CR_DEEPPWD_Pos) /*!< 0x20000000 */ #define ADC_CR_DEEPPWD ADC_CR_DEEPPWD_Msk /*!< ADC Deep power down Enable */ #define ADC_CR_ADCALDIF_Pos (30U) #define ADC_CR_ADCALDIF_Msk (0x1UL << ADC_CR_ADCALDIF_Pos) /*!< 0x40000000 */ #define ADC_CR_ADCALDIF ADC_CR_ADCALDIF_Msk /*!< ADC Differential Mode for calibration */ #define ADC_CR_ADCAL_Pos (31U) #define ADC_CR_ADCAL_Msk (0x1UL << ADC_CR_ADCAL_Pos) /*!< 0x80000000 */ #define ADC_CR_ADCAL ADC_CR_ADCAL_Msk /*!< ADC Calibration */ /******************** Bit definition for ADC_CFGR register ********************/ #define ADC_CFGR_DMNGT_Pos (0U) #define ADC_CFGR_DMNGT_Msk (0x3UL << ADC_CFGR_DMNGT_Pos) /*!< 0x00000003 */ #define ADC_CFGR_DMNGT ADC_CFGR_DMNGT_Msk /*!< ADC Data Management configuration */ #define ADC_CFGR_DMNGT_0 (0x1UL << ADC_CFGR_DMNGT_Pos) /*!< 0x00000001 */ #define ADC_CFGR_DMNGT_1 (0x2UL << ADC_CFGR_DMNGT_Pos) /*!< 0x00000002 */ #define ADC_CFGR_RES_Pos (2U) #define ADC_CFGR_RES_Msk (0x7UL << ADC_CFGR_RES_Pos) /*!< 0x0000001C */ #define ADC_CFGR_RES ADC_CFGR_RES_Msk /*!< ADC Data resolution */ #define ADC_CFGR_RES_0 (0x1UL << ADC_CFGR_RES_Pos) /*!< 0x00000004 */ #define ADC_CFGR_RES_1 (0x2UL << ADC_CFGR_RES_Pos) /*!< 0x00000008 */ #define ADC_CFGR_RES_2 (0x4UL << ADC_CFGR_RES_Pos) /*!< 0x00000010 */ #define ADC_CFGR_EXTSEL_Pos (5U) #define ADC_CFGR_EXTSEL_Msk (0x1FUL << ADC_CFGR_EXTSEL_Pos) /*!< 0x000003E0 */ #define ADC_CFGR_EXTSEL ADC_CFGR_EXTSEL_Msk /*!< ADC External trigger selection for regular group */ #define ADC_CFGR_EXTSEL_0 (0x01UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000020 */ #define ADC_CFGR_EXTSEL_1 (0x02UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000040 */ #define ADC_CFGR_EXTSEL_2 (0x04UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000080 */ #define ADC_CFGR_EXTSEL_3 (0x08UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000100 */ #define ADC_CFGR_EXTSEL_4 (0x10UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000200 */ #define ADC_CFGR_EXTEN_Pos (10U) #define ADC_CFGR_EXTEN_Msk (0x3UL << ADC_CFGR_EXTEN_Pos) /*!< 0x00000C00 */ #define ADC_CFGR_EXTEN ADC_CFGR_EXTEN_Msk /*!< ADC External trigger enable and polarity selection for regular channels */ #define ADC_CFGR_EXTEN_0 (0x1UL << ADC_CFGR_EXTEN_Pos) /*!< 0x00000400 */ #define ADC_CFGR_EXTEN_1 (0x2UL << ADC_CFGR_EXTEN_Pos) /*!< 0x00000800 */ #define ADC_CFGR_OVRMOD_Pos (12U) #define ADC_CFGR_OVRMOD_Msk (0x1UL << ADC_CFGR_OVRMOD_Pos) /*!< 0x00001000 */ #define ADC_CFGR_OVRMOD ADC_CFGR_OVRMOD_Msk /*!< ADC overrun mode */ #define ADC_CFGR_CONT_Pos (13U) #define ADC_CFGR_CONT_Msk (0x1UL << ADC_CFGR_CONT_Pos) /*!< 0x00002000 */ #define ADC_CFGR_CONT ADC_CFGR_CONT_Msk /*!< ADC Single/continuous conversion mode for regular conversion */ #define ADC_CFGR_AUTDLY_Pos (14U) #define ADC_CFGR_AUTDLY_Msk (0x1UL << ADC_CFGR_AUTDLY_Pos) /*!< 0x00004000 */ #define ADC_CFGR_AUTDLY ADC_CFGR_AUTDLY_Msk /*!< ADC Delayed conversion mode */ #define ADC_CFGR_DISCEN_Pos (16U) #define ADC_CFGR_DISCEN_Msk (0x1UL << ADC_CFGR_DISCEN_Pos) /*!< 0x00010000 */ #define ADC_CFGR_DISCEN ADC_CFGR_DISCEN_Msk /*!< ADC Discontinuous mode for regular channels */ #define ADC_CFGR_DISCNUM_Pos (17U) #define ADC_CFGR_DISCNUM_Msk (0x7UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x000E0000 */ #define ADC_CFGR_DISCNUM ADC_CFGR_DISCNUM_Msk /*!< ADC Discontinuous mode channel count */ #define ADC_CFGR_DISCNUM_0 (0x1UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x00020000 */ #define ADC_CFGR_DISCNUM_1 (0x2UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x00040000 */ #define ADC_CFGR_DISCNUM_2 (0x4UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x00080000 */ #define ADC_CFGR_JDISCEN_Pos (20U) #define ADC_CFGR_JDISCEN_Msk (0x1UL << ADC_CFGR_JDISCEN_Pos) /*!< 0x00100000 */ #define ADC_CFGR_JDISCEN ADC_CFGR_JDISCEN_Msk /*!< ADC Discontinuous mode on injected channels */ #define ADC_CFGR_JQM_Pos (21U) #define ADC_CFGR_JQM_Msk (0x1UL << ADC_CFGR_JQM_Pos) /*!< 0x00200000 */ #define ADC_CFGR_JQM ADC_CFGR_JQM_Msk /*!< ADC JSQR Queue mode */ #define ADC_CFGR_AWD1SGL_Pos (22U) #define ADC_CFGR_AWD1SGL_Msk (0x1UL << ADC_CFGR_AWD1SGL_Pos) /*!< 0x00400000 */ #define ADC_CFGR_AWD1SGL ADC_CFGR_AWD1SGL_Msk /*!< Enable the watchdog 1 on a single channel or on all channels */ #define ADC_CFGR_AWD1EN_Pos (23U) #define ADC_CFGR_AWD1EN_Msk (0x1UL << ADC_CFGR_AWD1EN_Pos) /*!< 0x00800000 */ #define ADC_CFGR_AWD1EN ADC_CFGR_AWD1EN_Msk /*!< ADC Analog watchdog 1 enable on regular Channels */ #define ADC_CFGR_JAWD1EN_Pos (24U) #define ADC_CFGR_JAWD1EN_Msk (0x1UL << ADC_CFGR_JAWD1EN_Pos) /*!< 0x01000000 */ #define ADC_CFGR_JAWD1EN ADC_CFGR_JAWD1EN_Msk /*!< ADC Analog watchdog 1 enable on injected Channels */ #define ADC_CFGR_JAUTO_Pos (25U) #define ADC_CFGR_JAUTO_Msk (0x1UL << ADC_CFGR_JAUTO_Pos) /*!< 0x02000000 */ #define ADC_CFGR_JAUTO ADC_CFGR_JAUTO_Msk /*!< ADC Automatic injected group conversion */ #define ADC_CFGR_AWD1CH_Pos (26U) #define ADC_CFGR_AWD1CH_Msk (0x1FUL << ADC_CFGR_AWD1CH_Pos) /*!< 0x7C000000 */ #define ADC_CFGR_AWD1CH ADC_CFGR_AWD1CH_Msk /*!< ADC Analog watchdog 1 Channel selection */ #define ADC_CFGR_AWD1CH_0 (0x01UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x04000000 */ #define ADC_CFGR_AWD1CH_1 (0x02UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x08000000 */ #define ADC_CFGR_AWD1CH_2 (0x04UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x10000000 */ #define ADC_CFGR_AWD1CH_3 (0x08UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x20000000 */ #define ADC_CFGR_AWD1CH_4 (0x10UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x40000000 */ #define ADC_CFGR_JQDIS_Pos (31U) #define ADC_CFGR_JQDIS_Msk (0x1UL << ADC_CFGR_JQDIS_Pos) /*!< 0x80000000 */ #define ADC_CFGR_JQDIS ADC_CFGR_JQDIS_Msk /*!< ADC Injected queue disable */ /******************** Bit definition for ADC_CFGR2 register ********************/ #define ADC_CFGR2_ROVSE_Pos (0U) #define ADC_CFGR2_ROVSE_Msk (0x1UL << ADC_CFGR2_ROVSE_Pos) /*!< 0x00000001 */ #define ADC_CFGR2_ROVSE ADC_CFGR2_ROVSE_Msk /*!< ADC Regular group oversampler enable */ #define ADC_CFGR2_JOVSE_Pos (1U) #define ADC_CFGR2_JOVSE_Msk (0x1UL << ADC_CFGR2_JOVSE_Pos) /*!< 0x00000002 */ #define ADC_CFGR2_JOVSE ADC_CFGR2_JOVSE_Msk /*!< ADC Injected group oversampler enable */ #define ADC_CFGR2_OVSS_Pos (5U) #define ADC_CFGR2_OVSS_Msk (0xFUL << ADC_CFGR2_OVSS_Pos) /*!< 0x000001E0 */ #define ADC_CFGR2_OVSS ADC_CFGR2_OVSS_Msk /*!< ADC Regular Oversampling shift */ #define ADC_CFGR2_OVSS_0 (0x1UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000020 */ #define ADC_CFGR2_OVSS_1 (0x2UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000040 */ #define ADC_CFGR2_OVSS_2 (0x4UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000080 */ #define ADC_CFGR2_OVSS_3 (0x8UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000100 */ #define ADC_CFGR2_TROVS_Pos (9U) #define ADC_CFGR2_TROVS_Msk (0x1UL << ADC_CFGR2_TROVS_Pos) /*!< 0x00000200 */ #define ADC_CFGR2_TROVS ADC_CFGR2_TROVS_Msk /*!< ADC Triggered regular Oversampling */ #define ADC_CFGR2_ROVSM_Pos (10U) #define ADC_CFGR2_ROVSM_Msk (0x1UL << ADC_CFGR2_ROVSM_Pos) /*!< 0x00000400 */ #define ADC_CFGR2_ROVSM ADC_CFGR2_ROVSM_Msk /*!< ADC Regular oversampling mode */ #define ADC_CFGR2_RSHIFT1_Pos (11U) #define ADC_CFGR2_RSHIFT1_Msk (0x1UL << ADC_CFGR2_RSHIFT1_Pos) /*!< 0x00000800 */ #define ADC_CFGR2_RSHIFT1 ADC_CFGR2_RSHIFT1_Msk /*!< ADC Right-shift data after Offset 1 correction */ #define ADC_CFGR2_RSHIFT2_Pos (12U) #define ADC_CFGR2_RSHIFT2_Msk (0x1UL << ADC_CFGR2_RSHIFT2_Pos) /*!< 0x00001000 */ #define ADC_CFGR2_RSHIFT2 ADC_CFGR2_RSHIFT2_Msk /*!< ADC Right-shift data after Offset 2 correction */ #define ADC_CFGR2_RSHIFT3_Pos (13U) #define ADC_CFGR2_RSHIFT3_Msk (0x1UL << ADC_CFGR2_RSHIFT3_Pos) /*!< 0x00002000 */ #define ADC_CFGR2_RSHIFT3 ADC_CFGR2_RSHIFT3_Msk /*!< ADC Right-shift data after Offset 3 correction */ #define ADC_CFGR2_RSHIFT4_Pos (14U) #define ADC_CFGR2_RSHIFT4_Msk (0x1UL << ADC_CFGR2_RSHIFT4_Pos) /*!< 0x00004000 */ #define ADC_CFGR2_RSHIFT4 ADC_CFGR2_RSHIFT4_Msk /*!< ADC Right-shift data after Offset 4 correction */ #define ADC_CFGR2_OVSR_Pos (16U) #define ADC_CFGR2_OVSR_Msk (0x3FFUL << ADC_CFGR2_OVSR_Pos) /*!< 0x03FF0000 */ #define ADC_CFGR2_OVSR ADC_CFGR2_OVSR_Msk /*!< ADC oversampling Ratio */ #define ADC_CFGR2_OVSR_0 (0x001UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00010000 */ #define ADC_CFGR2_OVSR_1 (0x002UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00020000 */ #define ADC_CFGR2_OVSR_2 (0x004UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00040000 */ #define ADC_CFGR2_OVSR_3 (0x008UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00080000 */ #define ADC_CFGR2_OVSR_4 (0x010UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00100000 */ #define ADC_CFGR2_OVSR_5 (0x020UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00200000 */ #define ADC_CFGR2_OVSR_6 (0x040UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00400000 */ #define ADC_CFGR2_OVSR_7 (0x080UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00800000 */ #define ADC_CFGR2_OVSR_8 (0x100UL << ADC_CFGR2_OVSR_Pos) /*!< 0x01000000 */ #define ADC_CFGR2_OVSR_9 (0x200UL << ADC_CFGR2_OVSR_Pos) /*!< 0x02000000 */ #define ADC_CFGR2_LSHIFT_Pos (28U) #define ADC_CFGR2_LSHIFT_Msk (0xFUL << ADC_CFGR2_LSHIFT_Pos) /*!< 0xF0000000 */ #define ADC_CFGR2_LSHIFT ADC_CFGR2_LSHIFT_Msk /*!< ADC Left shift factor */ #define ADC_CFGR2_LSHIFT_0 (0x1UL << ADC_CFGR2_LSHIFT_Pos) /*!< 0x10000000 */ #define ADC_CFGR2_LSHIFT_1 (0x2UL << ADC_CFGR2_LSHIFT_Pos) /*!< 0x20000000 */ #define ADC_CFGR2_LSHIFT_2 (0x4UL << ADC_CFGR2_LSHIFT_Pos) /*!< 0x40000000 */ #define ADC_CFGR2_LSHIFT_3 (0x8UL << ADC_CFGR2_LSHIFT_Pos) /*!< 0x80000000 */ /******************** Bit definition for ADC_SMPR1 register ********************/ #define ADC_SMPR1_SMP0_Pos (0U) #define ADC_SMPR1_SMP0_Msk (0x7UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000007 */ #define ADC_SMPR1_SMP0 ADC_SMPR1_SMP0_Msk /*!< ADC Channel 0 Sampling time selection */ #define ADC_SMPR1_SMP0_0 (0x1UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000001 */ #define ADC_SMPR1_SMP0_1 (0x2UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000002 */ #define ADC_SMPR1_SMP0_2 (0x4UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000004 */ #define ADC_SMPR1_SMP1_Pos (3U) #define ADC_SMPR1_SMP1_Msk (0x7UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000038 */ #define ADC_SMPR1_SMP1 ADC_SMPR1_SMP1_Msk /*!< ADC Channel 1 Sampling time selection */ #define ADC_SMPR1_SMP1_0 (0x1UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000008 */ #define ADC_SMPR1_SMP1_1 (0x2UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000010 */ #define ADC_SMPR1_SMP1_2 (0x4UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000020 */ #define ADC_SMPR1_SMP2_Pos (6U) #define ADC_SMPR1_SMP2_Msk (0x7UL << ADC_SMPR1_SMP2_Pos) /*!< 0x000001C0 */ #define ADC_SMPR1_SMP2 ADC_SMPR1_SMP2_Msk /*!< ADC Channel 2 Sampling time selection */ #define ADC_SMPR1_SMP2_0 (0x1UL << ADC_SMPR1_SMP2_Pos) /*!< 0x00000040 */ #define ADC_SMPR1_SMP2_1 (0x2UL << ADC_SMPR1_SMP2_Pos) /*!< 0x00000080 */ #define ADC_SMPR1_SMP2_2 (0x4UL << ADC_SMPR1_SMP2_Pos) /*!< 0x00000100 */ #define ADC_SMPR1_SMP3_Pos (9U) #define ADC_SMPR1_SMP3_Msk (0x7UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000E00 */ #define ADC_SMPR1_SMP3 ADC_SMPR1_SMP3_Msk /*!< ADC Channel 3 Sampling time selection */ #define ADC_SMPR1_SMP3_0 (0x1UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000200 */ #define ADC_SMPR1_SMP3_1 (0x2UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000400 */ #define ADC_SMPR1_SMP3_2 (0x4UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000800 */ #define ADC_SMPR1_SMP4_Pos (12U) #define ADC_SMPR1_SMP4_Msk (0x7UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00007000 */ #define ADC_SMPR1_SMP4 ADC_SMPR1_SMP4_Msk /*!< ADC Channel 4 Sampling time selection */ #define ADC_SMPR1_SMP4_0 (0x1UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00001000 */ #define ADC_SMPR1_SMP4_1 (0x2UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00002000 */ #define ADC_SMPR1_SMP4_2 (0x4UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00004000 */ #define ADC_SMPR1_SMP5_Pos (15U) #define ADC_SMPR1_SMP5_Msk (0x7UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00038000 */ #define ADC_SMPR1_SMP5 ADC_SMPR1_SMP5_Msk /*!< ADC Channel 5 Sampling time selection */ #define ADC_SMPR1_SMP5_0 (0x1UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00008000 */ #define ADC_SMPR1_SMP5_1 (0x2UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00010000 */ #define ADC_SMPR1_SMP5_2 (0x4UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00020000 */ #define ADC_SMPR1_SMP6_Pos (18U) #define ADC_SMPR1_SMP6_Msk (0x7UL << ADC_SMPR1_SMP6_Pos) /*!< 0x001C0000 */ #define ADC_SMPR1_SMP6 ADC_SMPR1_SMP6_Msk /*!< ADC Channel 6 Sampling time selection */ #define ADC_SMPR1_SMP6_0 (0x1UL << ADC_SMPR1_SMP6_Pos) /*!< 0x00040000 */ #define ADC_SMPR1_SMP6_1 (0x2UL << ADC_SMPR1_SMP6_Pos) /*!< 0x00080000 */ #define ADC_SMPR1_SMP6_2 (0x4UL << ADC_SMPR1_SMP6_Pos) /*!< 0x00100000 */ #define ADC_SMPR1_SMP7_Pos (21U) #define ADC_SMPR1_SMP7_Msk (0x7UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00E00000 */ #define ADC_SMPR1_SMP7 ADC_SMPR1_SMP7_Msk /*!< ADC Channel 7 Sampling time selection */ #define ADC_SMPR1_SMP7_0 (0x1UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00200000 */ #define ADC_SMPR1_SMP7_1 (0x2UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00400000 */ #define ADC_SMPR1_SMP7_2 (0x4UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00800000 */ #define ADC_SMPR1_SMP8_Pos (24U) #define ADC_SMPR1_SMP8_Msk (0x7UL << ADC_SMPR1_SMP8_Pos) /*!< 0x07000000 */ #define ADC_SMPR1_SMP8 ADC_SMPR1_SMP8_Msk /*!< ADC Channel 8 Sampling time selection */ #define ADC_SMPR1_SMP8_0 (0x1UL << ADC_SMPR1_SMP8_Pos) /*!< 0x01000000 */ #define ADC_SMPR1_SMP8_1 (0x2UL << ADC_SMPR1_SMP8_Pos) /*!< 0x02000000 */ #define ADC_SMPR1_SMP8_2 (0x4UL << ADC_SMPR1_SMP8_Pos) /*!< 0x04000000 */ #define ADC_SMPR1_SMP9_Pos (27U) #define ADC_SMPR1_SMP9_Msk (0x7UL << ADC_SMPR1_SMP9_Pos) /*!< 0x38000000 */ #define ADC_SMPR1_SMP9 ADC_SMPR1_SMP9_Msk /*!< ADC Channel 9 Sampling time selection */ #define ADC_SMPR1_SMP9_0 (0x1UL << ADC_SMPR1_SMP9_Pos) /*!< 0x08000000 */ #define ADC_SMPR1_SMP9_1 (0x2UL << ADC_SMPR1_SMP9_Pos) /*!< 0x10000000 */ #define ADC_SMPR1_SMP9_2 (0x4UL << ADC_SMPR1_SMP9_Pos) /*!< 0x20000000 */ /******************** Bit definition for ADC_SMPR2 register ********************/ #define ADC_SMPR2_SMP10_Pos (0U) #define ADC_SMPR2_SMP10_Msk (0x7UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000007 */ #define ADC_SMPR2_SMP10 ADC_SMPR2_SMP10_Msk /*!< ADC Channel 10 Sampling time selection */ #define ADC_SMPR2_SMP10_0 (0x1UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000001 */ #define ADC_SMPR2_SMP10_1 (0x2UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000002 */ #define ADC_SMPR2_SMP10_2 (0x4UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000004 */ #define ADC_SMPR2_SMP11_Pos (3U) #define ADC_SMPR2_SMP11_Msk (0x7UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000038 */ #define ADC_SMPR2_SMP11 ADC_SMPR2_SMP11_Msk /*!< ADC Channel 11 Sampling time selection */ #define ADC_SMPR2_SMP11_0 (0x1UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000008 */ #define ADC_SMPR2_SMP11_1 (0x2UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000010 */ #define ADC_SMPR2_SMP11_2 (0x4UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000020 */ #define ADC_SMPR2_SMP12_Pos (6U) #define ADC_SMPR2_SMP12_Msk (0x7UL << ADC_SMPR2_SMP12_Pos) /*!< 0x000001C0 */ #define ADC_SMPR2_SMP12 ADC_SMPR2_SMP12_Msk /*!< ADC Channel 12 Sampling time selection */ #define ADC_SMPR2_SMP12_0 (0x1UL << ADC_SMPR2_SMP12_Pos) /*!< 0x00000040 */ #define ADC_SMPR2_SMP12_1 (0x2UL << ADC_SMPR2_SMP12_Pos) /*!< 0x00000080 */ #define ADC_SMPR2_SMP12_2 (0x4UL << ADC_SMPR2_SMP12_Pos) /*!< 0x00000100 */ #define ADC_SMPR2_SMP13_Pos (9U) #define ADC_SMPR2_SMP13_Msk (0x7UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000E00 */ #define ADC_SMPR2_SMP13 ADC_SMPR2_SMP13_Msk /*!< ADC Channel 13 Sampling time selection */ #define ADC_SMPR2_SMP13_0 (0x1UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000200 */ #define ADC_SMPR2_SMP13_1 (0x2UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000400 */ #define ADC_SMPR2_SMP13_2 (0x4UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000800 */ #define ADC_SMPR2_SMP14_Pos (12U) #define ADC_SMPR2_SMP14_Msk (0x7UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00007000 */ #define ADC_SMPR2_SMP14 ADC_SMPR2_SMP14_Msk /*!< ADC Channel 14 Sampling time selection */ #define ADC_SMPR2_SMP14_0 (0x1UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00001000 */ #define ADC_SMPR2_SMP14_1 (0x2UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00002000 */ #define ADC_SMPR2_SMP14_2 (0x4UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00004000 */ #define ADC_SMPR2_SMP15_Pos (15U) #define ADC_SMPR2_SMP15_Msk (0x7UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00038000 */ #define ADC_SMPR2_SMP15 ADC_SMPR2_SMP15_Msk /*!< ADC Channel 15 Sampling time selection */ #define ADC_SMPR2_SMP15_0 (0x1UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00008000 */ #define ADC_SMPR2_SMP15_1 (0x2UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00010000 */ #define ADC_SMPR2_SMP15_2 (0x4UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00020000 */ #define ADC_SMPR2_SMP16_Pos (18U) #define ADC_SMPR2_SMP16_Msk (0x7UL << ADC_SMPR2_SMP16_Pos) /*!< 0x001C0000 */ #define ADC_SMPR2_SMP16 ADC_SMPR2_SMP16_Msk /*!< ADC Channel 16 Sampling time selection */ #define ADC_SMPR2_SMP16_0 (0x1UL << ADC_SMPR2_SMP16_Pos) /*!< 0x00040000 */ #define ADC_SMPR2_SMP16_1 (0x2UL << ADC_SMPR2_SMP16_Pos) /*!< 0x00080000 */ #define ADC_SMPR2_SMP16_2 (0x4UL << ADC_SMPR2_SMP16_Pos) /*!< 0x00100000 */ #define ADC_SMPR2_SMP17_Pos (21U) #define ADC_SMPR2_SMP17_Msk (0x7UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00E00000 */ #define ADC_SMPR2_SMP17 ADC_SMPR2_SMP17_Msk /*!< ADC Channel 17 Sampling time selection */ #define ADC_SMPR2_SMP17_0 (0x1UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00200000 */ #define ADC_SMPR2_SMP17_1 (0x2UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00400000 */ #define ADC_SMPR2_SMP17_2 (0x4UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00800000 */ #define ADC_SMPR2_SMP18_Pos (24U) #define ADC_SMPR2_SMP18_Msk (0x7UL << ADC_SMPR2_SMP18_Pos) /*!< 0x07000000 */ #define ADC_SMPR2_SMP18 ADC_SMPR2_SMP18_Msk /*!< ADC Channel 18 Sampling time selection */ #define ADC_SMPR2_SMP18_0 (0x1UL << ADC_SMPR2_SMP18_Pos) /*!< 0x01000000 */ #define ADC_SMPR2_SMP18_1 (0x2UL << ADC_SMPR2_SMP18_Pos) /*!< 0x02000000 */ #define ADC_SMPR2_SMP18_2 (0x4UL << ADC_SMPR2_SMP18_Pos) /*!< 0x04000000 */ #define ADC_SMPR2_SMP19_Pos (27U) #define ADC_SMPR2_SMP19_Msk (0x7UL << ADC_SMPR2_SMP19_Pos) /*!< 0x38000000 */ #define ADC_SMPR2_SMP19 ADC_SMPR2_SMP19_Msk /*!< ADC Channel 19 Sampling time selection */ #define ADC_SMPR2_SMP19_0 (0x1UL << ADC_SMPR2_SMP19_Pos) /*!< 0x08000000 */ #define ADC_SMPR2_SMP19_1 (0x2UL << ADC_SMPR2_SMP19_Pos) /*!< 0x10000000 */ #define ADC_SMPR2_SMP19_2 (0x4UL << ADC_SMPR2_SMP19_Pos) /*!< 0x20000000 */ /******************** Bit definition for ADC_PCSEL register ********************/ #define ADC_PCSEL_PCSEL_Pos (0U) #define ADC_PCSEL_PCSEL_Msk (0xFFFFFUL << ADC_PCSEL_PCSEL_Pos) /*!< 0x000FFFFF */ #define ADC_PCSEL_PCSEL ADC_PCSEL_PCSEL_Msk /*!< ADC pre channel selection */ #define ADC_PCSEL_PCSEL_0 (0x00001UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00000001 */ #define ADC_PCSEL_PCSEL_1 (0x00002UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00000002 */ #define ADC_PCSEL_PCSEL_2 (0x00004UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00000004 */ #define ADC_PCSEL_PCSEL_3 (0x00008UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00000008 */ #define ADC_PCSEL_PCSEL_4 (0x00010UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00000010 */ #define ADC_PCSEL_PCSEL_5 (0x00020UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00000020 */ #define ADC_PCSEL_PCSEL_6 (0x00040UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00000040 */ #define ADC_PCSEL_PCSEL_7 (0x00080UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00000080 */ #define ADC_PCSEL_PCSEL_8 (0x00100UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00000100 */ #define ADC_PCSEL_PCSEL_9 (0x00200UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00000200 */ #define ADC_PCSEL_PCSEL_10 (0x00400UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00000400 */ #define ADC_PCSEL_PCSEL_11 (0x00800UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00000800 */ #define ADC_PCSEL_PCSEL_12 (0x01000UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00001000 */ #define ADC_PCSEL_PCSEL_13 (0x02000UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00002000 */ #define ADC_PCSEL_PCSEL_14 (0x04000UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00004000 */ #define ADC_PCSEL_PCSEL_15 (0x08000UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00008000 */ #define ADC_PCSEL_PCSEL_16 (0x10000UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00010000 */ #define ADC_PCSEL_PCSEL_17 (0x20000UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00020000 */ #define ADC_PCSEL_PCSEL_18 (0x40000UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00040000 */ #define ADC_PCSEL_PCSEL_19 (0x80000UL << ADC_PCSEL_PCSEL_Pos) /*!< 0x00080000 */ /***************** Bit definition for ADC_LTR1, 2, 3 registers *****************/ #define ADC_LTR_LT_Pos (0U) #define ADC_LTR_LT_Msk (0x3FFFFFFUL << ADC_LTR_LT_Pos) /*!< 0x03FFFFFF */ #define ADC_LTR_LT ADC_LTR_LT_Msk /*!< ADC Analog watchdog 1, 2 and 3 lower threshold */ /***************** Bit definition for ADC_HTR1, 2, 3 registers ****************/ #define ADC_HTR_HT_Pos (0U) #define ADC_HTR_HT_Msk (0x3FFFFFFUL << ADC_HTR_HT_Pos) /*!< 0x03FFFFFF */ #define ADC_HTR_HT ADC_HTR_HT_Msk /*!< ADC Analog watchdog 1,2 and 3 higher threshold */ /******************** Bit definition for ADC_SQR1 register ********************/ #define ADC_SQR1_L_Pos (0U) #define ADC_SQR1_L_Msk (0xFUL << ADC_SQR1_L_Pos) /*!< 0x0000000F */ #define ADC_SQR1_L ADC_SQR1_L_Msk /*!< ADC regular channel sequence length */ #define ADC_SQR1_L_0 (0x1UL << ADC_SQR1_L_Pos) /*!< 0x00000001 */ #define ADC_SQR1_L_1 (0x2UL << ADC_SQR1_L_Pos) /*!< 0x00000002 */ #define ADC_SQR1_L_2 (0x4UL << ADC_SQR1_L_Pos) /*!< 0x00000004 */ #define ADC_SQR1_L_3 (0x8UL << ADC_SQR1_L_Pos) /*!< 0x00000008 */ #define ADC_SQR1_SQ1_Pos (6U) #define ADC_SQR1_SQ1_Msk (0x1FUL << ADC_SQR1_SQ1_Pos) /*!< 0x000007C0 */ #define ADC_SQR1_SQ1 ADC_SQR1_SQ1_Msk /*!< ADC 1st conversion in regular sequence */ #define ADC_SQR1_SQ1_0 (0x01UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000040 */ #define ADC_SQR1_SQ1_1 (0x02UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000080 */ #define ADC_SQR1_SQ1_2 (0x04UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000100 */ #define ADC_SQR1_SQ1_3 (0x08UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000200 */ #define ADC_SQR1_SQ1_4 (0x10UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000400 */ #define ADC_SQR1_SQ2_Pos (12U) #define ADC_SQR1_SQ2_Msk (0x1FUL << ADC_SQR1_SQ2_Pos) /*!< 0x0001F000 */ #define ADC_SQR1_SQ2 ADC_SQR1_SQ2_Msk /*!< ADC 2nd conversion in regular sequence */ #define ADC_SQR1_SQ2_0 (0x01UL << ADC_SQR1_SQ2_Pos) /*!< 0x00001000 */ #define ADC_SQR1_SQ2_1 (0x02UL << ADC_SQR1_SQ2_Pos) /*!< 0x00002000 */ #define ADC_SQR1_SQ2_2 (0x04UL << ADC_SQR1_SQ2_Pos) /*!< 0x00004000 */ #define ADC_SQR1_SQ2_3 (0x08UL << ADC_SQR1_SQ2_Pos) /*!< 0x00008000 */ #define ADC_SQR1_SQ2_4 (0x10UL << ADC_SQR1_SQ2_Pos) /*!< 0x00010000 */ #define ADC_SQR1_SQ3_Pos (18U) #define ADC_SQR1_SQ3_Msk (0x1FUL << ADC_SQR1_SQ3_Pos) /*!< 0x007C0000 */ #define ADC_SQR1_SQ3 ADC_SQR1_SQ3_Msk /*!< ADC 3rd conversion in regular sequence */ #define ADC_SQR1_SQ3_0 (0x01UL << ADC_SQR1_SQ3_Pos) /*!< 0x00040000 */ #define ADC_SQR1_SQ3_1 (0x02UL << ADC_SQR1_SQ3_Pos) /*!< 0x00080000 */ #define ADC_SQR1_SQ3_2 (0x04UL << ADC_SQR1_SQ3_Pos) /*!< 0x00100000 */ #define ADC_SQR1_SQ3_3 (0x08UL << ADC_SQR1_SQ3_Pos) /*!< 0x00200000 */ #define ADC_SQR1_SQ3_4 (0x10UL << ADC_SQR1_SQ3_Pos) /*!< 0x00400000 */ #define ADC_SQR1_SQ4_Pos (24U) #define ADC_SQR1_SQ4_Msk (0x1FUL << ADC_SQR1_SQ4_Pos) /*!< 0x1F000000 */ #define ADC_SQR1_SQ4 ADC_SQR1_SQ4_Msk /*!< ADC 4th conversion in regular sequence */ #define ADC_SQR1_SQ4_0 (0x01UL << ADC_SQR1_SQ4_Pos) /*!< 0x01000000 */ #define ADC_SQR1_SQ4_1 (0x02UL << ADC_SQR1_SQ4_Pos) /*!< 0x02000000 */ #define ADC_SQR1_SQ4_2 (0x04UL << ADC_SQR1_SQ4_Pos) /*!< 0x04000000 */ #define ADC_SQR1_SQ4_3 (0x08UL << ADC_SQR1_SQ4_Pos) /*!< 0x08000000 */ #define ADC_SQR1_SQ4_4 (0x10UL << ADC_SQR1_SQ4_Pos) /*!< 0x10000000 */ /******************** Bit definition for ADC_SQR2 register ********************/ #define ADC_SQR2_SQ5_Pos (0U) #define ADC_SQR2_SQ5_Msk (0x1FUL << ADC_SQR2_SQ5_Pos) /*!< 0x0000001F */ #define ADC_SQR2_SQ5 ADC_SQR2_SQ5_Msk /*!< ADC 5th conversion in regular sequence */ #define ADC_SQR2_SQ5_0 (0x01UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000001 */ #define ADC_SQR2_SQ5_1 (0x02UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000002 */ #define ADC_SQR2_SQ5_2 (0x04UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000004 */ #define ADC_SQR2_SQ5_3 (0x08UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000008 */ #define ADC_SQR2_SQ5_4 (0x10UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000010 */ #define ADC_SQR2_SQ6_Pos (6U) #define ADC_SQR2_SQ6_Msk (0x1FUL << ADC_SQR2_SQ6_Pos) /*!< 0x000007C0 */ #define ADC_SQR2_SQ6 ADC_SQR2_SQ6_Msk /*!< ADC 6th conversion in regular sequence */ #define ADC_SQR2_SQ6_0 (0x01UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000040 */ #define ADC_SQR2_SQ6_1 (0x02UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000080 */ #define ADC_SQR2_SQ6_2 (0x04UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000100 */ #define ADC_SQR2_SQ6_3 (0x08UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000200 */ #define ADC_SQR2_SQ6_4 (0x10UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000400 */ #define ADC_SQR2_SQ7_Pos (12U) #define ADC_SQR2_SQ7_Msk (0x1FUL << ADC_SQR2_SQ7_Pos) /*!< 0x0001F000 */ #define ADC_SQR2_SQ7 ADC_SQR2_SQ7_Msk /*!< ADC 7th conversion in regular sequence */ #define ADC_SQR2_SQ7_0 (0x01UL << ADC_SQR2_SQ7_Pos) /*!< 0x00001000 */ #define ADC_SQR2_SQ7_1 (0x02UL << ADC_SQR2_SQ7_Pos) /*!< 0x00002000 */ #define ADC_SQR2_SQ7_2 (0x04UL << ADC_SQR2_SQ7_Pos) /*!< 0x00004000 */ #define ADC_SQR2_SQ7_3 (0x08UL << ADC_SQR2_SQ7_Pos) /*!< 0x00008000 */ #define ADC_SQR2_SQ7_4 (0x10UL << ADC_SQR2_SQ7_Pos) /*!< 0x00010000 */ #define ADC_SQR2_SQ8_Pos (18U) #define ADC_SQR2_SQ8_Msk (0x1FUL << ADC_SQR2_SQ8_Pos) /*!< 0x007C0000 */ #define ADC_SQR2_SQ8 ADC_SQR2_SQ8_Msk /*!< ADC 8th conversion in regular sequence */ #define ADC_SQR2_SQ8_0 (0x01UL << ADC_SQR2_SQ8_Pos) /*!< 0x00040000 */ #define ADC_SQR2_SQ8_1 (0x02UL << ADC_SQR2_SQ8_Pos) /*!< 0x00080000 */ #define ADC_SQR2_SQ8_2 (0x04UL << ADC_SQR2_SQ8_Pos) /*!< 0x00100000 */ #define ADC_SQR2_SQ8_3 (0x08UL << ADC_SQR2_SQ8_Pos) /*!< 0x00200000 */ #define ADC_SQR2_SQ8_4 (0x10UL << ADC_SQR2_SQ8_Pos) /*!< 0x00400000 */ #define ADC_SQR2_SQ9_Pos (24U) #define ADC_SQR2_SQ9_Msk (0x1FUL << ADC_SQR2_SQ9_Pos) /*!< 0x1F000000 */ #define ADC_SQR2_SQ9 ADC_SQR2_SQ9_Msk /*!< ADC 9th conversion in regular sequence */ #define ADC_SQR2_SQ9_0 (0x01UL << ADC_SQR2_SQ9_Pos) /*!< 0x01000000 */ #define ADC_SQR2_SQ9_1 (0x02UL << ADC_SQR2_SQ9_Pos) /*!< 0x02000000 */ #define ADC_SQR2_SQ9_2 (0x04UL << ADC_SQR2_SQ9_Pos) /*!< 0x04000000 */ #define ADC_SQR2_SQ9_3 (0x08UL << ADC_SQR2_SQ9_Pos) /*!< 0x08000000 */ #define ADC_SQR2_SQ9_4 (0x10UL << ADC_SQR2_SQ9_Pos) /*!< 0x10000000 */ /******************** Bit definition for ADC_SQR3 register ********************/ #define ADC_SQR3_SQ10_Pos (0U) #define ADC_SQR3_SQ10_Msk (0x1FUL << ADC_SQR3_SQ10_Pos) /*!< 0x0000001F */ #define ADC_SQR3_SQ10 ADC_SQR3_SQ10_Msk /*!< ADC 10th conversion in regular sequence */ #define ADC_SQR3_SQ10_0 (0x01UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000001 */ #define ADC_SQR3_SQ10_1 (0x02UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000002 */ #define ADC_SQR3_SQ10_2 (0x04UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000004 */ #define ADC_SQR3_SQ10_3 (0x08UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000008 */ #define ADC_SQR3_SQ10_4 (0x10UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000010 */ #define ADC_SQR3_SQ11_Pos (6U) #define ADC_SQR3_SQ11_Msk (0x1FUL << ADC_SQR3_SQ11_Pos) /*!< 0x000007C0 */ #define ADC_SQR3_SQ11 ADC_SQR3_SQ11_Msk /*!< ADC 11th conversion in regular sequence */ #define ADC_SQR3_SQ11_0 (0x01UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000040 */ #define ADC_SQR3_SQ11_1 (0x02UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000080 */ #define ADC_SQR3_SQ11_2 (0x04UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000100 */ #define ADC_SQR3_SQ11_3 (0x08UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000200 */ #define ADC_SQR3_SQ11_4 (0x10UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000400 */ #define ADC_SQR3_SQ12_Pos (12U) #define ADC_SQR3_SQ12_Msk (0x1FUL << ADC_SQR3_SQ12_Pos) /*!< 0x0001F000 */ #define ADC_SQR3_SQ12 ADC_SQR3_SQ12_Msk /*!< ADC 12th conversion in regular sequence */ #define ADC_SQR3_SQ12_0 (0x01UL << ADC_SQR3_SQ12_Pos) /*!< 0x00001000 */ #define ADC_SQR3_SQ12_1 (0x02UL << ADC_SQR3_SQ12_Pos) /*!< 0x00002000 */ #define ADC_SQR3_SQ12_2 (0x04UL << ADC_SQR3_SQ12_Pos) /*!< 0x00004000 */ #define ADC_SQR3_SQ12_3 (0x08UL << ADC_SQR3_SQ12_Pos) /*!< 0x00008000 */ #define ADC_SQR3_SQ12_4 (0x10UL << ADC_SQR3_SQ12_Pos) /*!< 0x00010000 */ #define ADC_SQR3_SQ13_Pos (18U) #define ADC_SQR3_SQ13_Msk (0x1FUL << ADC_SQR3_SQ13_Pos) /*!< 0x007C0000 */ #define ADC_SQR3_SQ13 ADC_SQR3_SQ13_Msk /*!< ADC 13th conversion in regular sequence */ #define ADC_SQR3_SQ13_0 (0x01UL << ADC_SQR3_SQ13_Pos) /*!< 0x00040000 */ #define ADC_SQR3_SQ13_1 (0x02UL << ADC_SQR3_SQ13_Pos) /*!< 0x00080000 */ #define ADC_SQR3_SQ13_2 (0x04UL << ADC_SQR3_SQ13_Pos) /*!< 0x00100000 */ #define ADC_SQR3_SQ13_3 (0x08UL << ADC_SQR3_SQ13_Pos) /*!< 0x00200000 */ #define ADC_SQR3_SQ13_4 (0x10UL << ADC_SQR3_SQ13_Pos) /*!< 0x00400000 */ #define ADC_SQR3_SQ14_Pos (24U) #define ADC_SQR3_SQ14_Msk (0x1FUL << ADC_SQR3_SQ14_Pos) /*!< 0x1F000000 */ #define ADC_SQR3_SQ14 ADC_SQR3_SQ14_Msk /*!< ADC 14th conversion in regular sequence */ #define ADC_SQR3_SQ14_0 (0x01UL << ADC_SQR3_SQ14_Pos) /*!< 0x01000000 */ #define ADC_SQR3_SQ14_1 (0x02UL << ADC_SQR3_SQ14_Pos) /*!< 0x02000000 */ #define ADC_SQR3_SQ14_2 (0x04UL << ADC_SQR3_SQ14_Pos) /*!< 0x04000000 */ #define ADC_SQR3_SQ14_3 (0x08UL << ADC_SQR3_SQ14_Pos) /*!< 0x08000000 */ #define ADC_SQR3_SQ14_4 (0x10UL << ADC_SQR3_SQ14_Pos) /*!< 0x10000000 */ /******************** Bit definition for ADC_SQR4 register ********************/ #define ADC_SQR4_SQ15_Pos (0U) #define ADC_SQR4_SQ15_Msk (0x1FUL << ADC_SQR4_SQ15_Pos) /*!< 0x0000001F */ #define ADC_SQR4_SQ15 ADC_SQR4_SQ15_Msk /*!< ADC 15th conversion in regular sequence */ #define ADC_SQR4_SQ15_0 (0x01UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000001 */ #define ADC_SQR4_SQ15_1 (0x02UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000002 */ #define ADC_SQR4_SQ15_2 (0x04UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000004 */ #define ADC_SQR4_SQ15_3 (0x08UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000008 */ #define ADC_SQR4_SQ15_4 (0x10UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000010 */ #define ADC_SQR4_SQ16_Pos (6U) #define ADC_SQR4_SQ16_Msk (0x1FUL << ADC_SQR4_SQ16_Pos) /*!< 0x000007C0 */ #define ADC_SQR4_SQ16 ADC_SQR4_SQ16_Msk /*!< ADC 16th conversion in regular sequence */ #define ADC_SQR4_SQ16_0 (0x01UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000040 */ #define ADC_SQR4_SQ16_1 (0x02UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000080 */ #define ADC_SQR4_SQ16_2 (0x04UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000100 */ #define ADC_SQR4_SQ16_3 (0x08UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000200 */ #define ADC_SQR4_SQ16_4 (0x10UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000400 */ /******************** Bit definition for ADC_DR register ********************/ #define ADC_DR_RDATA_Pos (0U) #define ADC_DR_RDATA_Msk (0xFFFFFFFFUL << ADC_DR_RDATA_Pos) /*!< 0xFFFFFFFF */ #define ADC_DR_RDATA ADC_DR_RDATA_Msk /*!< ADC regular Data converted */ /******************** Bit definition for ADC_JSQR register ********************/ #define ADC_JSQR_JL_Pos (0U) #define ADC_JSQR_JL_Msk (0x3UL << ADC_JSQR_JL_Pos) /*!< 0x00000003 */ #define ADC_JSQR_JL ADC_JSQR_JL_Msk /*!< ADC injected channel sequence length */ #define ADC_JSQR_JL_0 (0x1UL << ADC_JSQR_JL_Pos) /*!< 0x00000001 */ #define ADC_JSQR_JL_1 (0x2UL << ADC_JSQR_JL_Pos) /*!< 0x00000002 */ #define ADC_JSQR_JEXTSEL_Pos (2U) #define ADC_JSQR_JEXTSEL_Msk (0x1FUL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x0000007C */ #define ADC_JSQR_JEXTSEL ADC_JSQR_JEXTSEL_Msk /*!< ADC external trigger selection for injected group */ #define ADC_JSQR_JEXTSEL_0 (0x01UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000004 */ #define ADC_JSQR_JEXTSEL_1 (0x02UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000008 */ #define ADC_JSQR_JEXTSEL_2 (0x04UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000010 */ #define ADC_JSQR_JEXTSEL_3 (0x08UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000020 */ #define ADC_JSQR_JEXTSEL_4 (0x10UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000040 */ #define ADC_JSQR_JEXTEN_Pos (7U) #define ADC_JSQR_JEXTEN_Msk (0x3UL << ADC_JSQR_JEXTEN_Pos) /*!< 0x00000180 */ #define ADC_JSQR_JEXTEN ADC_JSQR_JEXTEN_Msk /*!< ADC external trigger enable and polarity selection for injected channels */ #define ADC_JSQR_JEXTEN_0 (0x1UL << ADC_JSQR_JEXTEN_Pos) /*!< 0x00000080 */ #define ADC_JSQR_JEXTEN_1 (0x2UL << ADC_JSQR_JEXTEN_Pos) /*!< 0x00000100 */ #define ADC_JSQR_JSQ1_Pos (9U) #define ADC_JSQR_JSQ1_Msk (0x1FUL << ADC_JSQR_JSQ1_Pos) /*!< 0x00003E00 */ #define ADC_JSQR_JSQ1 ADC_JSQR_JSQ1_Msk /*!< ADC 1st conversion in injected sequence */ #define ADC_JSQR_JSQ1_0 (0x01UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00000200 */ #define ADC_JSQR_JSQ1_1 (0x02UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00000400 */ #define ADC_JSQR_JSQ1_2 (0x04UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00000800 */ #define ADC_JSQR_JSQ1_3 (0x08UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00001000 */ #define ADC_JSQR_JSQ1_4 (0x10UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00002000 */ #define ADC_JSQR_JSQ2_Pos (15U) #define ADC_JSQR_JSQ2_Msk (0x1FUL << ADC_JSQR_JSQ2_Pos) /*!< 0x000F8000 */ #define ADC_JSQR_JSQ2 ADC_JSQR_JSQ2_Msk /*!< ADC 2nd conversion in injected sequence */ #define ADC_JSQR_JSQ2_0 (0x01UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00008000 */ #define ADC_JSQR_JSQ2_1 (0x02UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00010000 */ #define ADC_JSQR_JSQ2_2 (0x04UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00020000 */ #define ADC_JSQR_JSQ2_3 (0x08UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00040000 */ #define ADC_JSQR_JSQ2_4 (0x10UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00080000 */ #define ADC_JSQR_JSQ3_Pos (21U) #define ADC_JSQR_JSQ3_Msk (0x1FUL << ADC_JSQR_JSQ3_Pos) /*!< 0x03E00000 */ #define ADC_JSQR_JSQ3 ADC_JSQR_JSQ3_Msk /*!< ADC 3rd conversion in injected sequence */ #define ADC_JSQR_JSQ3_0 (0x01UL << ADC_JSQR_JSQ3_Pos) /*!< 0x00200000 */ #define ADC_JSQR_JSQ3_1 (0x02UL << ADC_JSQR_JSQ3_Pos) /*!< 0x00400000 */ #define ADC_JSQR_JSQ3_2 (0x04UL << ADC_JSQR_JSQ3_Pos) /*!< 0x00800000 */ #define ADC_JSQR_JSQ3_3 (0x08UL << ADC_JSQR_JSQ3_Pos) /*!< 0x01000000 */ #define ADC_JSQR_JSQ3_4 (0x10UL << ADC_JSQR_JSQ3_Pos) /*!< 0x02000000 */ #define ADC_JSQR_JSQ4_Pos (27U) #define ADC_JSQR_JSQ4_Msk (0x1FUL << ADC_JSQR_JSQ4_Pos) /*!< 0xF8000000 */ #define ADC_JSQR_JSQ4 ADC_JSQR_JSQ4_Msk /*!< ADC 4th conversion in injected sequence */ #define ADC_JSQR_JSQ4_0 (0x01UL << ADC_JSQR_JSQ4_Pos) /*!< 0x08000000 */ #define ADC_JSQR_JSQ4_1 (0x02UL << ADC_JSQR_JSQ4_Pos) /*!< 0x10000000 */ #define ADC_JSQR_JSQ4_2 (0x04UL << ADC_JSQR_JSQ4_Pos) /*!< 0x20000000 */ #define ADC_JSQR_JSQ4_3 (0x08UL << ADC_JSQR_JSQ4_Pos) /*!< 0x40000000 */ #define ADC_JSQR_JSQ4_4 (0x10UL << ADC_JSQR_JSQ4_Pos) /*!< 0x80000000 */ /******************** Bit definition for ADC_OFR1 register ********************/ #define ADC_OFR1_OFFSET1_Pos (0U) #define ADC_OFR1_OFFSET1_Msk (0x3FFFFFFUL << ADC_OFR1_OFFSET1_Pos) /*!< 0x03FFFFFF */ #define ADC_OFR1_OFFSET1 ADC_OFR1_OFFSET1_Msk /*!< ADC data offset 1 for channel programmed into bits OFFSET1_CH[4:0] */ #define ADC_OFR1_OFFSET1_0 (0x0000001UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00000001 */ #define ADC_OFR1_OFFSET1_1 (0x0000002UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00000002 */ #define ADC_OFR1_OFFSET1_2 (0x0000004UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00000004 */ #define ADC_OFR1_OFFSET1_3 (0x0000008UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00000008 */ #define ADC_OFR1_OFFSET1_4 (0x0000010UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00000010 */ #define ADC_OFR1_OFFSET1_5 (0x0000020UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00000020 */ #define ADC_OFR1_OFFSET1_6 (0x0000040UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00000040 */ #define ADC_OFR1_OFFSET1_7 (0x0000080UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00000080 */ #define ADC_OFR1_OFFSET1_8 (0x0000100UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00000100 */ #define ADC_OFR1_OFFSET1_9 (0x0000200UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00000200 */ #define ADC_OFR1_OFFSET1_10 (0x0000400UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00000400 */ #define ADC_OFR1_OFFSET1_11 (0x0000800UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00000800 */ #define ADC_OFR1_OFFSET1_12 (0x0001000UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00001000 */ #define ADC_OFR1_OFFSET1_13 (0x0002000UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00002000 */ #define ADC_OFR1_OFFSET1_14 (0x0004000UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00004000 */ #define ADC_OFR1_OFFSET1_15 (0x0008000UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00008000 */ #define ADC_OFR1_OFFSET1_16 (0x0010000UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00010000 */ #define ADC_OFR1_OFFSET1_17 (0x0020000UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00020000 */ #define ADC_OFR1_OFFSET1_18 (0x0040000UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00040000 */ #define ADC_OFR1_OFFSET1_19 (0x0080000UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00080000 */ #define ADC_OFR1_OFFSET1_20 (0x0100000UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00100000 */ #define ADC_OFR1_OFFSET1_21 (0x0200000UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00200000 */ #define ADC_OFR1_OFFSET1_22 (0x0400000UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00400000 */ #define ADC_OFR1_OFFSET1_23 (0x0800000UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00800000 */ #define ADC_OFR1_OFFSET1_24 (0x1000000UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x01000000 */ #define ADC_OFR1_OFFSET1_25 (0x2000000UL << ADC_OFR1_OFFSET1_Pos) /*!< 0x02000000 */ #define ADC_OFR1_OFFSET1_CH_Pos (26U) #define ADC_OFR1_OFFSET1_CH_Msk (0x1FUL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x7C000000 */ #define ADC_OFR1_OFFSET1_CH ADC_OFR1_OFFSET1_CH_Msk /*!< ADC Channel selection for the data offset 1 */ #define ADC_OFR1_OFFSET1_CH_0 (0x01UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x04000000 */ #define ADC_OFR1_OFFSET1_CH_1 (0x02UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x08000000 */ #define ADC_OFR1_OFFSET1_CH_2 (0x04UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x10000000 */ #define ADC_OFR1_OFFSET1_CH_3 (0x08UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x20000000 */ #define ADC_OFR1_OFFSET1_CH_4 (0x10UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x40000000 */ #define ADC_OFR1_SSATE_Pos (31U) #define ADC_OFR1_SSATE_Msk (0x1UL << ADC_OFR1_SSATE_Pos) /*!< 0x80000000 */ #define ADC_OFR1_SSATE ADC_OFR1_SSATE_Msk /*!< ADC Signed saturation Enable */ /******************** Bit definition for ADC_OFR2 register ********************/ #define ADC_OFR2_OFFSET2_Pos (0U) #define ADC_OFR2_OFFSET2_Msk (0x3FFFFFFUL << ADC_OFR2_OFFSET2_Pos) /*!< 0x03FFFFFF */ #define ADC_OFR2_OFFSET2 ADC_OFR2_OFFSET2_Msk /*!< ADC data offset 2 for channel programmed into bits OFFSET2_CH[4:0] */ #define ADC_OFR2_OFFSET2_0 (0x0000001UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00000001 */ #define ADC_OFR2_OFFSET2_1 (0x0000002UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00000002 */ #define ADC_OFR2_OFFSET2_2 (0x0000004UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00000004 */ #define ADC_OFR2_OFFSET2_3 (0x0000008UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00000008 */ #define ADC_OFR2_OFFSET2_4 (0x0000010UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00000010 */ #define ADC_OFR2_OFFSET2_5 (0x0000020UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00000020 */ #define ADC_OFR2_OFFSET2_6 (0x0000040UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00000040 */ #define ADC_OFR2_OFFSET2_7 (0x0000080UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00000080 */ #define ADC_OFR2_OFFSET2_8 (0x0000100UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00000100 */ #define ADC_OFR2_OFFSET2_9 (0x0000200UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00000200 */ #define ADC_OFR2_OFFSET2_10 (0x0000400UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00000400 */ #define ADC_OFR2_OFFSET2_11 (0x0000800UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00000800 */ #define ADC_OFR2_OFFSET2_12 (0x0001000UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00001000 */ #define ADC_OFR2_OFFSET2_13 (0x0002000UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00002000 */ #define ADC_OFR2_OFFSET2_14 (0x0004000UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00004000 */ #define ADC_OFR2_OFFSET2_15 (0x0008000UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00008000 */ #define ADC_OFR2_OFFSET2_16 (0x0010000UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00010000 */ #define ADC_OFR2_OFFSET2_17 (0x0020000UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00020000 */ #define ADC_OFR2_OFFSET2_18 (0x0040000UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00040000 */ #define ADC_OFR2_OFFSET2_19 (0x0080000UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00080000 */ #define ADC_OFR2_OFFSET2_20 (0x0100000UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00100000 */ #define ADC_OFR2_OFFSET2_21 (0x0200000UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00200000 */ #define ADC_OFR2_OFFSET2_22 (0x0400000UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00400000 */ #define ADC_OFR2_OFFSET2_23 (0x0800000UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00800000 */ #define ADC_OFR2_OFFSET2_24 (0x1000000UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x01000000 */ #define ADC_OFR2_OFFSET2_25 (0x2000000UL << ADC_OFR2_OFFSET2_Pos) /*!< 0x02000000 */ #define ADC_OFR2_OFFSET2_CH_Pos (26U) #define ADC_OFR2_OFFSET2_CH_Msk (0x1FUL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x7C000000 */ #define ADC_OFR2_OFFSET2_CH ADC_OFR2_OFFSET2_CH_Msk /*!< ADC Channel selection for the data offset 2 */ #define ADC_OFR2_OFFSET2_CH_0 (0x01UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x04000000 */ #define ADC_OFR2_OFFSET2_CH_1 (0x02UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x08000000 */ #define ADC_OFR2_OFFSET2_CH_2 (0x04UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x10000000 */ #define ADC_OFR2_OFFSET2_CH_3 (0x08UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x20000000 */ #define ADC_OFR2_OFFSET2_CH_4 (0x10UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x40000000 */ #define ADC_OFR2_SSATE_Pos (31U) #define ADC_OFR2_SSATE_Msk (0x1UL << ADC_OFR2_SSATE_Pos) /*!< 0x80000000 */ #define ADC_OFR2_SSATE ADC_OFR2_SSATE_Msk /*!< ADC Signed saturation Enable */ /******************** Bit definition for ADC_OFR3 register ********************/ #define ADC_OFR3_OFFSET3_Pos (0U) #define ADC_OFR3_OFFSET3_Msk (0x3FFFFFFUL << ADC_OFR3_OFFSET3_Pos) /*!< 0x03FFFFFF */ #define ADC_OFR3_OFFSET3 ADC_OFR3_OFFSET3_Msk /*!< ADC data offset 3 for channel programmed into bits OFFSET3_CH[4:0] */ #define ADC_OFR3_OFFSET3_0 (0x0000001UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00000001 */ #define ADC_OFR3_OFFSET3_1 (0x0000002UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00000002 */ #define ADC_OFR3_OFFSET3_2 (0x0000004UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00000004 */ #define ADC_OFR3_OFFSET3_3 (0x0000008UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00000008 */ #define ADC_OFR3_OFFSET3_4 (0x0000010UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00000010 */ #define ADC_OFR3_OFFSET3_5 (0x0000020UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00000020 */ #define ADC_OFR3_OFFSET3_6 (0x0000040UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00000040 */ #define ADC_OFR3_OFFSET3_7 (0x0000080UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00000080 */ #define ADC_OFR3_OFFSET3_8 (0x0000100UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00000100 */ #define ADC_OFR3_OFFSET3_9 (0x0000200UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00000200 */ #define ADC_OFR3_OFFSET3_10 (0x0000400UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00000400 */ #define ADC_OFR3_OFFSET3_11 (0x0000800UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00000800 */ #define ADC_OFR3_OFFSET3_12 (0x0001000UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00001000 */ #define ADC_OFR3_OFFSET3_13 (0x0002000UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00002000 */ #define ADC_OFR3_OFFSET3_14 (0x0004000UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00004000 */ #define ADC_OFR3_OFFSET3_15 (0x0008000UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00008000 */ #define ADC_OFR3_OFFSET3_16 (0x0010000UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00010000 */ #define ADC_OFR3_OFFSET3_17 (0x0020000UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00020000 */ #define ADC_OFR3_OFFSET3_18 (0x0040000UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00040000 */ #define ADC_OFR3_OFFSET3_19 (0x0080000UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00080000 */ #define ADC_OFR3_OFFSET3_20 (0x0100000UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00100000 */ #define ADC_OFR3_OFFSET3_21 (0x0200000UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00200000 */ #define ADC_OFR3_OFFSET3_22 (0x0400000UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00400000 */ #define ADC_OFR3_OFFSET3_23 (0x0800000UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00800000 */ #define ADC_OFR3_OFFSET3_24 (0x1000000UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x01000000 */ #define ADC_OFR3_OFFSET3_25 (0x2000000UL << ADC_OFR3_OFFSET3_Pos) /*!< 0x02000000 */ #define ADC_OFR3_OFFSET3_CH_Pos (26U) #define ADC_OFR3_OFFSET3_CH_Msk (0x1FUL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x7C000000 */ #define ADC_OFR3_OFFSET3_CH ADC_OFR3_OFFSET3_CH_Msk /*!< ADC Channel selection for the data offset 3 */ #define ADC_OFR3_OFFSET3_CH_0 (0x01UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x04000000 */ #define ADC_OFR3_OFFSET3_CH_1 (0x02UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x08000000 */ #define ADC_OFR3_OFFSET3_CH_2 (0x04UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x10000000 */ #define ADC_OFR3_OFFSET3_CH_3 (0x08UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x20000000 */ #define ADC_OFR3_OFFSET3_CH_4 (0x10UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x40000000 */ #define ADC_OFR3_SSATE_Pos (31U) #define ADC_OFR3_SSATE_Msk (0x1UL << ADC_OFR3_SSATE_Pos) /*!< 0x80000000 */ #define ADC_OFR3_SSATE ADC_OFR3_SSATE_Msk /*!< ADC Signed saturation Enable */ /******************** Bit definition for ADC_OFR4 register ********************/ #define ADC_OFR4_OFFSET4_Pos (0U) #define ADC_OFR4_OFFSET4_Msk (0x3FFFFFFUL << ADC_OFR4_OFFSET4_Pos) /*!< 0x03FFFFFF */ #define ADC_OFR4_OFFSET4 ADC_OFR4_OFFSET4_Msk /*!< ADC data offset 4 for channel programmed into bits OFFSET4_CH[4:0] */ #define ADC_OFR4_OFFSET4_0 (0x0000001UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00000001 */ #define ADC_OFR4_OFFSET4_1 (0x0000002UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00000002 */ #define ADC_OFR4_OFFSET4_2 (0x0000004UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00000004 */ #define ADC_OFR4_OFFSET4_3 (0x0000008UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00000008 */ #define ADC_OFR4_OFFSET4_4 (0x0000010UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00000010 */ #define ADC_OFR4_OFFSET4_5 (0x0000020UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00000020 */ #define ADC_OFR4_OFFSET4_6 (0x0000040UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00000040 */ #define ADC_OFR4_OFFSET4_7 (0x0000080UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00000080 */ #define ADC_OFR4_OFFSET4_8 (0x0000100UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00000100 */ #define ADC_OFR4_OFFSET4_9 (0x0000200UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00000200 */ #define ADC_OFR4_OFFSET4_10 (0x0000400UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00000400 */ #define ADC_OFR4_OFFSET4_11 (0x0000800UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00000800 */ #define ADC_OFR4_OFFSET4_12 (0x0001000UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00001000 */ #define ADC_OFR4_OFFSET4_13 (0x0002000UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00002000 */ #define ADC_OFR4_OFFSET4_14 (0x0004000UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00004000 */ #define ADC_OFR4_OFFSET4_15 (0x0008000UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00008000 */ #define ADC_OFR4_OFFSET4_16 (0x0010000UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00010000 */ #define ADC_OFR4_OFFSET4_17 (0x0020000UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00020000 */ #define ADC_OFR4_OFFSET4_18 (0x0040000UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00040000 */ #define ADC_OFR4_OFFSET4_19 (0x0080000UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00080000 */ #define ADC_OFR4_OFFSET4_20 (0x0100000UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00100000 */ #define ADC_OFR4_OFFSET4_21 (0x0200000UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00200000 */ #define ADC_OFR4_OFFSET4_22 (0x0400000UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00400000 */ #define ADC_OFR4_OFFSET4_23 (0x0800000UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00800000 */ #define ADC_OFR4_OFFSET4_24 (0x1000000UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x01000000 */ #define ADC_OFR4_OFFSET4_25 (0x2000000UL << ADC_OFR4_OFFSET4_Pos) /*!< 0x02000000 */ #define ADC_OFR4_OFFSET4_CH_Pos (26U) #define ADC_OFR4_OFFSET4_CH_Msk (0x1FUL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x7C000000 */ #define ADC_OFR4_OFFSET4_CH ADC_OFR4_OFFSET4_CH_Msk /*!< ADC Channel selection for the data offset 4 */ #define ADC_OFR4_OFFSET4_CH_0 (0x01UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x04000000 */ #define ADC_OFR4_OFFSET4_CH_1 (0x02UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x08000000 */ #define ADC_OFR4_OFFSET4_CH_2 (0x04UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x10000000 */ #define ADC_OFR4_OFFSET4_CH_3 (0x08UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x20000000 */ #define ADC_OFR4_OFFSET4_CH_4 (0x10UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x40000000 */ #define ADC_OFR4_SSATE_Pos (31U) #define ADC_OFR4_SSATE_Msk (0x1UL << ADC_OFR4_SSATE_Pos) /*!< 0x80000000 */ #define ADC_OFR4_SSATE ADC_OFR4_SSATE_Msk /*!< ADC Signed saturation Enable */ /******************** Bit definition for ADC_JDR1 register ********************/ #define ADC_JDR1_JDATA_Pos (0U) #define ADC_JDR1_JDATA_Msk (0xFFFFFFFFUL << ADC_JDR1_JDATA_Pos) /*!< 0xFFFFFFFF */ #define ADC_JDR1_JDATA ADC_JDR1_JDATA_Msk /*!< ADC Injected DATA */ #define ADC_JDR1_JDATA_0 (0x00000001UL << ADC_JDR1_JDATA_Pos) /*!< 0x00000001 */ #define ADC_JDR1_JDATA_1 (0x00000002UL << ADC_JDR1_JDATA_Pos) /*!< 0x00000002 */ #define ADC_JDR1_JDATA_2 (0x00000004UL << ADC_JDR1_JDATA_Pos) /*!< 0x00000004 */ #define ADC_JDR1_JDATA_3 (0x00000008UL << ADC_JDR1_JDATA_Pos) /*!< 0x00000008 */ #define ADC_JDR1_JDATA_4 (0x00000010UL << ADC_JDR1_JDATA_Pos) /*!< 0x00000010 */ #define ADC_JDR1_JDATA_5 (0x00000020UL << ADC_JDR1_JDATA_Pos) /*!< 0x00000020 */ #define ADC_JDR1_JDATA_6 (0x00000040UL << ADC_JDR1_JDATA_Pos) /*!< 0x00000040 */ #define ADC_JDR1_JDATA_7 (0x00000080UL << ADC_JDR1_JDATA_Pos) /*!< 0x00000080 */ #define ADC_JDR1_JDATA_8 (0x00000100UL << ADC_JDR1_JDATA_Pos) /*!< 0x00000100 */ #define ADC_JDR1_JDATA_9 (0x00000200UL << ADC_JDR1_JDATA_Pos) /*!< 0x00000200 */ #define ADC_JDR1_JDATA_10 (0x00000400UL << ADC_JDR1_JDATA_Pos) /*!< 0x00000400 */ #define ADC_JDR1_JDATA_11 (0x00000800UL << ADC_JDR1_JDATA_Pos) /*!< 0x00000800 */ #define ADC_JDR1_JDATA_12 (0x00001000UL << ADC_JDR1_JDATA_Pos) /*!< 0x00001000 */ #define ADC_JDR1_JDATA_13 (0x00002000UL << ADC_JDR1_JDATA_Pos) /*!< 0x00002000 */ #define ADC_JDR1_JDATA_14 (0x00004000UL << ADC_JDR1_JDATA_Pos) /*!< 0x00004000 */ #define ADC_JDR1_JDATA_15 (0x00008000UL << ADC_JDR1_JDATA_Pos) /*!< 0x00008000 */ #define ADC_JDR1_JDATA_16 (0x00010000UL << ADC_JDR1_JDATA_Pos) /*!< 0x00010000 */ #define ADC_JDR1_JDATA_17 (0x00020000UL << ADC_JDR1_JDATA_Pos) /*!< 0x00020000 */ #define ADC_JDR1_JDATA_18 (0x00040000UL << ADC_JDR1_JDATA_Pos) /*!< 0x00040000 */ #define ADC_JDR1_JDATA_19 (0x00080000UL << ADC_JDR1_JDATA_Pos) /*!< 0x00080000 */ #define ADC_JDR1_JDATA_20 (0x00100000UL << ADC_JDR1_JDATA_Pos) /*!< 0x00100000 */ #define ADC_JDR1_JDATA_21 (0x00200000UL << ADC_JDR1_JDATA_Pos) /*!< 0x00200000 */ #define ADC_JDR1_JDATA_22 (0x00400000UL << ADC_JDR1_JDATA_Pos) /*!< 0x00400000 */ #define ADC_JDR1_JDATA_23 (0x00800000UL << ADC_JDR1_JDATA_Pos) /*!< 0x00800000 */ #define ADC_JDR1_JDATA_24 (0x01000000UL << ADC_JDR1_JDATA_Pos) /*!< 0x01000000 */ #define ADC_JDR1_JDATA_25 (0x02000000UL << ADC_JDR1_JDATA_Pos) /*!< 0x02000000 */ #define ADC_JDR1_JDATA_26 (0x04000000UL << ADC_JDR1_JDATA_Pos) /*!< 0x04000000 */ #define ADC_JDR1_JDATA_27 (0x08000000UL << ADC_JDR1_JDATA_Pos) /*!< 0x08000000 */ #define ADC_JDR1_JDATA_28 (0x10000000UL << ADC_JDR1_JDATA_Pos) /*!< 0x10000000 */ #define ADC_JDR1_JDATA_29 (0x20000000UL << ADC_JDR1_JDATA_Pos) /*!< 0x20000000 */ #define ADC_JDR1_JDATA_30 (0x40000000UL << ADC_JDR1_JDATA_Pos) /*!< 0x40000000 */ #define ADC_JDR1_JDATA_31 (0x80000000UL << ADC_JDR1_JDATA_Pos) /*!< 0x80000000 */ /******************** Bit definition for ADC_JDR2 register ********************/ #define ADC_JDR2_JDATA_Pos (0U) #define ADC_JDR2_JDATA_Msk (0xFFFFFFFFUL << ADC_JDR2_JDATA_Pos) /*!< 0xFFFFFFFF */ #define ADC_JDR2_JDATA ADC_JDR2_JDATA_Msk /*!< ADC Injected DATA */ #define ADC_JDR2_JDATA_0 (0x00000001UL << ADC_JDR2_JDATA_Pos) /*!< 0x00000001 */ #define ADC_JDR2_JDATA_1 (0x00000002UL << ADC_JDR2_JDATA_Pos) /*!< 0x00000002 */ #define ADC_JDR2_JDATA_2 (0x00000004UL << ADC_JDR2_JDATA_Pos) /*!< 0x00000004 */ #define ADC_JDR2_JDATA_3 (0x00000008UL << ADC_JDR2_JDATA_Pos) /*!< 0x00000008 */ #define ADC_JDR2_JDATA_4 (0x00000010UL << ADC_JDR2_JDATA_Pos) /*!< 0x00000010 */ #define ADC_JDR2_JDATA_5 (0x00000020UL << ADC_JDR2_JDATA_Pos) /*!< 0x00000020 */ #define ADC_JDR2_JDATA_6 (0x00000040UL << ADC_JDR2_JDATA_Pos) /*!< 0x00000040 */ #define ADC_JDR2_JDATA_7 (0x00000080UL << ADC_JDR2_JDATA_Pos) /*!< 0x00000080 */ #define ADC_JDR2_JDATA_8 (0x00000100UL << ADC_JDR2_JDATA_Pos) /*!< 0x00000100 */ #define ADC_JDR2_JDATA_9 (0x00000200UL << ADC_JDR2_JDATA_Pos) /*!< 0x00000200 */ #define ADC_JDR2_JDATA_10 (0x00000400UL << ADC_JDR2_JDATA_Pos) /*!< 0x00000400 */ #define ADC_JDR2_JDATA_11 (0x00000800UL << ADC_JDR2_JDATA_Pos) /*!< 0x00000800 */ #define ADC_JDR2_JDATA_12 (0x00001000UL << ADC_JDR2_JDATA_Pos) /*!< 0x00001000 */ #define ADC_JDR2_JDATA_13 (0x00002000UL << ADC_JDR2_JDATA_Pos) /*!< 0x00002000 */ #define ADC_JDR2_JDATA_14 (0x00004000UL << ADC_JDR2_JDATA_Pos) /*!< 0x00004000 */ #define ADC_JDR2_JDATA_15 (0x00008000UL << ADC_JDR2_JDATA_Pos) /*!< 0x00008000 */ #define ADC_JDR2_JDATA_16 (0x00010000UL << ADC_JDR2_JDATA_Pos) /*!< 0x00010000 */ #define ADC_JDR2_JDATA_17 (0x00020000UL << ADC_JDR2_JDATA_Pos) /*!< 0x00020000 */ #define ADC_JDR2_JDATA_18 (0x00040000UL << ADC_JDR2_JDATA_Pos) /*!< 0x00040000 */ #define ADC_JDR2_JDATA_19 (0x00080000UL << ADC_JDR2_JDATA_Pos) /*!< 0x00080000 */ #define ADC_JDR2_JDATA_20 (0x00100000UL << ADC_JDR2_JDATA_Pos) /*!< 0x00100000 */ #define ADC_JDR2_JDATA_21 (0x00200000UL << ADC_JDR2_JDATA_Pos) /*!< 0x00200000 */ #define ADC_JDR2_JDATA_22 (0x00400000UL << ADC_JDR2_JDATA_Pos) /*!< 0x00400000 */ #define ADC_JDR2_JDATA_23 (0x00800000UL << ADC_JDR2_JDATA_Pos) /*!< 0x00800000 */ #define ADC_JDR2_JDATA_24 (0x01000000UL << ADC_JDR2_JDATA_Pos) /*!< 0x01000000 */ #define ADC_JDR2_JDATA_25 (0x02000000UL << ADC_JDR2_JDATA_Pos) /*!< 0x02000000 */ #define ADC_JDR2_JDATA_26 (0x04000000UL << ADC_JDR2_JDATA_Pos) /*!< 0x04000000 */ #define ADC_JDR2_JDATA_27 (0x08000000UL << ADC_JDR2_JDATA_Pos) /*!< 0x08000000 */ #define ADC_JDR2_JDATA_28 (0x10000000UL << ADC_JDR2_JDATA_Pos) /*!< 0x10000000 */ #define ADC_JDR2_JDATA_29 (0x20000000UL << ADC_JDR2_JDATA_Pos) /*!< 0x20000000 */ #define ADC_JDR2_JDATA_30 (0x40000000UL << ADC_JDR2_JDATA_Pos) /*!< 0x40000000 */ #define ADC_JDR2_JDATA_31 (0x80000000UL << ADC_JDR2_JDATA_Pos) /*!< 0x80000000 */ /******************** Bit definition for ADC_JDR3 register ********************/ #define ADC_JDR3_JDATA_Pos (0U) #define ADC_JDR3_JDATA_Msk (0xFFFFFFFFUL << ADC_JDR3_JDATA_Pos) /*!< 0xFFFFFFFF */ #define ADC_JDR3_JDATA ADC_JDR3_JDATA_Msk /*!< ADC Injected DATA */ #define ADC_JDR3_JDATA_0 (0x00000001UL << ADC_JDR3_JDATA_Pos) /*!< 0x00000001 */ #define ADC_JDR3_JDATA_1 (0x00000002UL << ADC_JDR3_JDATA_Pos) /*!< 0x00000002 */ #define ADC_JDR3_JDATA_2 (0x00000004UL << ADC_JDR3_JDATA_Pos) /*!< 0x00000004 */ #define ADC_JDR3_JDATA_3 (0x00000008UL << ADC_JDR3_JDATA_Pos) /*!< 0x00000008 */ #define ADC_JDR3_JDATA_4 (0x00000010UL << ADC_JDR3_JDATA_Pos) /*!< 0x00000010 */ #define ADC_JDR3_JDATA_5 (0x00000020UL << ADC_JDR3_JDATA_Pos) /*!< 0x00000020 */ #define ADC_JDR3_JDATA_6 (0x00000040UL << ADC_JDR3_JDATA_Pos) /*!< 0x00000040 */ #define ADC_JDR3_JDATA_7 (0x00000080UL << ADC_JDR3_JDATA_Pos) /*!< 0x00000080 */ #define ADC_JDR3_JDATA_8 (0x00000100UL << ADC_JDR3_JDATA_Pos) /*!< 0x00000100 */ #define ADC_JDR3_JDATA_9 (0x00000200UL << ADC_JDR3_JDATA_Pos) /*!< 0x00000200 */ #define ADC_JDR3_JDATA_10 (0x00000400UL << ADC_JDR3_JDATA_Pos) /*!< 0x00000400 */ #define ADC_JDR3_JDATA_11 (0x00000800UL << ADC_JDR3_JDATA_Pos) /*!< 0x00000800 */ #define ADC_JDR3_JDATA_12 (0x00001000UL << ADC_JDR3_JDATA_Pos) /*!< 0x00001000 */ #define ADC_JDR3_JDATA_13 (0x00002000UL << ADC_JDR3_JDATA_Pos) /*!< 0x00002000 */ #define ADC_JDR3_JDATA_14 (0x00004000UL << ADC_JDR3_JDATA_Pos) /*!< 0x00004000 */ #define ADC_JDR3_JDATA_15 (0x00008000UL << ADC_JDR3_JDATA_Pos) /*!< 0x00008000 */ #define ADC_JDR3_JDATA_16 (0x00010000UL << ADC_JDR3_JDATA_Pos) /*!< 0x00010000 */ #define ADC_JDR3_JDATA_17 (0x00020000UL << ADC_JDR3_JDATA_Pos) /*!< 0x00020000 */ #define ADC_JDR3_JDATA_18 (0x00040000UL << ADC_JDR3_JDATA_Pos) /*!< 0x00040000 */ #define ADC_JDR3_JDATA_19 (0x00080000UL << ADC_JDR3_JDATA_Pos) /*!< 0x00080000 */ #define ADC_JDR3_JDATA_20 (0x00100000UL << ADC_JDR3_JDATA_Pos) /*!< 0x00100000 */ #define ADC_JDR3_JDATA_21 (0x00200000UL << ADC_JDR3_JDATA_Pos) /*!< 0x00200000 */ #define ADC_JDR3_JDATA_22 (0x00400000UL << ADC_JDR3_JDATA_Pos) /*!< 0x00400000 */ #define ADC_JDR3_JDATA_23 (0x00800000UL << ADC_JDR3_JDATA_Pos) /*!< 0x00800000 */ #define ADC_JDR3_JDATA_24 (0x01000000UL << ADC_JDR3_JDATA_Pos) /*!< 0x01000000 */ #define ADC_JDR3_JDATA_25 (0x02000000UL << ADC_JDR3_JDATA_Pos) /*!< 0x02000000 */ #define ADC_JDR3_JDATA_26 (0x04000000UL << ADC_JDR3_JDATA_Pos) /*!< 0x04000000 */ #define ADC_JDR3_JDATA_27 (0x08000000UL << ADC_JDR3_JDATA_Pos) /*!< 0x08000000 */ #define ADC_JDR3_JDATA_28 (0x10000000UL << ADC_JDR3_JDATA_Pos) /*!< 0x10000000 */ #define ADC_JDR3_JDATA_29 (0x20000000UL << ADC_JDR3_JDATA_Pos) /*!< 0x20000000 */ #define ADC_JDR3_JDATA_30 (0x40000000UL << ADC_JDR3_JDATA_Pos) /*!< 0x40000000 */ #define ADC_JDR3_JDATA_31 (0x80000000UL << ADC_JDR3_JDATA_Pos) /*!< 0x80000000 */ /******************** Bit definition for ADC_JDR4 register ********************/ #define ADC_JDR4_JDATA_Pos (0U) #define ADC_JDR4_JDATA_Msk (0xFFFFFFFFUL << ADC_JDR4_JDATA_Pos) /*!< 0xFFFFFFFF */ #define ADC_JDR4_JDATA ADC_JDR4_JDATA_Msk /*!< ADC Injected DATA */ #define ADC_JDR4_JDATA_0 (0x00000001UL << ADC_JDR4_JDATA_Pos) /*!< 0x00000001 */ #define ADC_JDR4_JDATA_1 (0x00000002UL << ADC_JDR4_JDATA_Pos) /*!< 0x00000002 */ #define ADC_JDR4_JDATA_2 (0x00000004UL << ADC_JDR4_JDATA_Pos) /*!< 0x00000004 */ #define ADC_JDR4_JDATA_3 (0x00000008UL << ADC_JDR4_JDATA_Pos) /*!< 0x00000008 */ #define ADC_JDR4_JDATA_4 (0x00000010UL << ADC_JDR4_JDATA_Pos) /*!< 0x00000010 */ #define ADC_JDR4_JDATA_5 (0x00000020UL << ADC_JDR4_JDATA_Pos) /*!< 0x00000020 */ #define ADC_JDR4_JDATA_6 (0x00000040UL << ADC_JDR4_JDATA_Pos) /*!< 0x00000040 */ #define ADC_JDR4_JDATA_7 (0x00000080UL << ADC_JDR4_JDATA_Pos) /*!< 0x00000080 */ #define ADC_JDR4_JDATA_8 (0x00000100UL << ADC_JDR4_JDATA_Pos) /*!< 0x00000100 */ #define ADC_JDR4_JDATA_9 (0x00000200UL << ADC_JDR4_JDATA_Pos) /*!< 0x00000200 */ #define ADC_JDR4_JDATA_10 (0x00000400UL << ADC_JDR4_JDATA_Pos) /*!< 0x00000400 */ #define ADC_JDR4_JDATA_11 (0x00000800UL << ADC_JDR4_JDATA_Pos) /*!< 0x00000800 */ #define ADC_JDR4_JDATA_12 (0x00001000UL << ADC_JDR4_JDATA_Pos) /*!< 0x00001000 */ #define ADC_JDR4_JDATA_13 (0x00002000UL << ADC_JDR4_JDATA_Pos) /*!< 0x00002000 */ #define ADC_JDR4_JDATA_14 (0x00004000UL << ADC_JDR4_JDATA_Pos) /*!< 0x00004000 */ #define ADC_JDR4_JDATA_15 (0x00008000UL << ADC_JDR4_JDATA_Pos) /*!< 0x00008000 */ #define ADC_JDR4_JDATA_16 (0x00010000UL << ADC_JDR4_JDATA_Pos) /*!< 0x00010000 */ #define ADC_JDR4_JDATA_17 (0x00020000UL << ADC_JDR4_JDATA_Pos) /*!< 0x00020000 */ #define ADC_JDR4_JDATA_18 (0x00040000UL << ADC_JDR4_JDATA_Pos) /*!< 0x00040000 */ #define ADC_JDR4_JDATA_19 (0x00080000UL << ADC_JDR4_JDATA_Pos) /*!< 0x00080000 */ #define ADC_JDR4_JDATA_20 (0x00100000UL << ADC_JDR4_JDATA_Pos) /*!< 0x00100000 */ #define ADC_JDR4_JDATA_21 (0x00200000UL << ADC_JDR4_JDATA_Pos) /*!< 0x00200000 */ #define ADC_JDR4_JDATA_22 (0x00400000UL << ADC_JDR4_JDATA_Pos) /*!< 0x00400000 */ #define ADC_JDR4_JDATA_23 (0x00800000UL << ADC_JDR4_JDATA_Pos) /*!< 0x00800000 */ #define ADC_JDR4_JDATA_24 (0x01000000UL << ADC_JDR4_JDATA_Pos) /*!< 0x01000000 */ #define ADC_JDR4_JDATA_25 (0x02000000UL << ADC_JDR4_JDATA_Pos) /*!< 0x02000000 */ #define ADC_JDR4_JDATA_26 (0x04000000UL << ADC_JDR4_JDATA_Pos) /*!< 0x04000000 */ #define ADC_JDR4_JDATA_27 (0x08000000UL << ADC_JDR4_JDATA_Pos) /*!< 0x08000000 */ #define ADC_JDR4_JDATA_28 (0x10000000UL << ADC_JDR4_JDATA_Pos) /*!< 0x10000000 */ #define ADC_JDR4_JDATA_29 (0x20000000UL << ADC_JDR4_JDATA_Pos) /*!< 0x20000000 */ #define ADC_JDR4_JDATA_30 (0x40000000UL << ADC_JDR4_JDATA_Pos) /*!< 0x40000000 */ #define ADC_JDR4_JDATA_31 (0x80000000UL << ADC_JDR4_JDATA_Pos) /*!< 0x80000000 */ /******************** Bit definition for ADC_AWD2CR register ********************/ #define ADC_AWD2CR_AWD2CH_Pos (0U) #define ADC_AWD2CR_AWD2CH_Msk (0xFFFFFUL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x000FFFFF */ #define ADC_AWD2CR_AWD2CH ADC_AWD2CR_AWD2CH_Msk /*!< ADC Analog watchdog 2 channel selection */ #define ADC_AWD2CR_AWD2CH_0 (0x00001UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000001 */ #define ADC_AWD2CR_AWD2CH_1 (0x00002UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000002 */ #define ADC_AWD2CR_AWD2CH_2 (0x00004UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000004 */ #define ADC_AWD2CR_AWD2CH_3 (0x00008UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000008 */ #define ADC_AWD2CR_AWD2CH_4 (0x00010UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000010 */ #define ADC_AWD2CR_AWD2CH_5 (0x00020UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000020 */ #define ADC_AWD2CR_AWD2CH_6 (0x00040UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000040 */ #define ADC_AWD2CR_AWD2CH_7 (0x00080UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000080 */ #define ADC_AWD2CR_AWD2CH_8 (0x00100UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000100 */ #define ADC_AWD2CR_AWD2CH_9 (0x00200UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000200 */ #define ADC_AWD2CR_AWD2CH_10 (0x00400UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000400 */ #define ADC_AWD2CR_AWD2CH_11 (0x00800UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000800 */ #define ADC_AWD2CR_AWD2CH_12 (0x01000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00001000 */ #define ADC_AWD2CR_AWD2CH_13 (0x02000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00002000 */ #define ADC_AWD2CR_AWD2CH_14 (0x04000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00004000 */ #define ADC_AWD2CR_AWD2CH_15 (0x08000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00008000 */ #define ADC_AWD2CR_AWD2CH_16 (0x10000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00010000 */ #define ADC_AWD2CR_AWD2CH_17 (0x20000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00020000 */ #define ADC_AWD2CR_AWD2CH_18 (0x40000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00040000 */ #define ADC_AWD2CR_AWD2CH_19 (0x80000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00080000 */ /******************** Bit definition for ADC_AWD3CR register ********************/ #define ADC_AWD3CR_AWD3CH_Pos (0U) #define ADC_AWD3CR_AWD3CH_Msk (0xFFFFFUL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x000FFFFF */ #define ADC_AWD3CR_AWD3CH ADC_AWD3CR_AWD3CH_Msk /*!< ADC Analog watchdog 2 channel selection */ #define ADC_AWD3CR_AWD3CH_0 (0x00001UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000001 */ #define ADC_AWD3CR_AWD3CH_1 (0x00002UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000002 */ #define ADC_AWD3CR_AWD3CH_2 (0x00004UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000004 */ #define ADC_AWD3CR_AWD3CH_3 (0x00008UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000008 */ #define ADC_AWD3CR_AWD3CH_4 (0x00010UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000010 */ #define ADC_AWD3CR_AWD3CH_5 (0x00020UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000020 */ #define ADC_AWD3CR_AWD3CH_6 (0x00040UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000040 */ #define ADC_AWD3CR_AWD3CH_7 (0x00080UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000080 */ #define ADC_AWD3CR_AWD3CH_8 (0x00100UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000100 */ #define ADC_AWD3CR_AWD3CH_9 (0x00200UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000200 */ #define ADC_AWD3CR_AWD3CH_10 (0x00400UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000400 */ #define ADC_AWD3CR_AWD3CH_11 (0x00800UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000800 */ #define ADC_AWD3CR_AWD3CH_12 (0x01000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00001000 */ #define ADC_AWD3CR_AWD3CH_13 (0x02000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00002000 */ #define ADC_AWD3CR_AWD3CH_14 (0x04000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00004000 */ #define ADC_AWD3CR_AWD3CH_15 (0x08000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00008000 */ #define ADC_AWD3CR_AWD3CH_16 (0x10000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00010000 */ #define ADC_AWD3CR_AWD3CH_17 (0x20000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00020000 */ #define ADC_AWD3CR_AWD3CH_18 (0x40000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00040000 */ #define ADC_AWD3CR_AWD3CH_19 (0x80000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00080000 */ /******************** Bit definition for ADC_DIFSEL register ********************/ #define ADC_DIFSEL_DIFSEL_Pos (0U) #define ADC_DIFSEL_DIFSEL_Msk (0xFFFFFUL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x000FFFFF */ #define ADC_DIFSEL_DIFSEL ADC_DIFSEL_DIFSEL_Msk /*!< ADC differential modes for channels 1 to 18 */ #define ADC_DIFSEL_DIFSEL_0 (0x00001UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000001 */ #define ADC_DIFSEL_DIFSEL_1 (0x00002UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000002 */ #define ADC_DIFSEL_DIFSEL_2 (0x00004UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000004 */ #define ADC_DIFSEL_DIFSEL_3 (0x00008UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000008 */ #define ADC_DIFSEL_DIFSEL_4 (0x00010UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000010 */ #define ADC_DIFSEL_DIFSEL_5 (0x00020UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000020 */ #define ADC_DIFSEL_DIFSEL_6 (0x00040UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000040 */ #define ADC_DIFSEL_DIFSEL_7 (0x00080UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000080 */ #define ADC_DIFSEL_DIFSEL_8 (0x00100UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000100 */ #define ADC_DIFSEL_DIFSEL_9 (0x00200UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000200 */ #define ADC_DIFSEL_DIFSEL_10 (0x00400UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000400 */ #define ADC_DIFSEL_DIFSEL_11 (0x00800UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000800 */ #define ADC_DIFSEL_DIFSEL_12 (0x01000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00001000 */ #define ADC_DIFSEL_DIFSEL_13 (0x02000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00002000 */ #define ADC_DIFSEL_DIFSEL_14 (0x04000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00004000 */ #define ADC_DIFSEL_DIFSEL_15 (0x08000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00008000 */ #define ADC_DIFSEL_DIFSEL_16 (0x10000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00010000 */ #define ADC_DIFSEL_DIFSEL_17 (0x20000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00020000 */ #define ADC_DIFSEL_DIFSEL_18 (0x40000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00040000 */ #define ADC_DIFSEL_DIFSEL_19 (0x80000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00080000 */ /******************** Bit definition for ADC_CALFACT register ********************/ #define ADC_CALFACT_CALFACT_S_Pos (0U) #define ADC_CALFACT_CALFACT_S_Msk (0x7FFUL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x000007FF */ #define ADC_CALFACT_CALFACT_S ADC_CALFACT_CALFACT_S_Msk /*!< ADC calibration factors in single-ended mode */ #define ADC_CALFACT_CALFACT_S_0 (0x001UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000001 */ #define ADC_CALFACT_CALFACT_S_1 (0x002UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000002 */ #define ADC_CALFACT_CALFACT_S_2 (0x004UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000004 */ #define ADC_CALFACT_CALFACT_S_3 (0x008UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000008 */ #define ADC_CALFACT_CALFACT_S_4 (0x010UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000010 */ #define ADC_CALFACT_CALFACT_S_5 (0x020UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000020 */ #define ADC_CALFACT_CALFACT_S_6 (0x040UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000040 */ #define ADC_CALFACT_CALFACT_S_7 (0x080UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000080 */ #define ADC_CALFACT_CALFACT_S_8 (0x100UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000100 */ #define ADC_CALFACT_CALFACT_S_9 (0x200UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000200 */ #define ADC_CALFACT_CALFACT_S_10 (0x400UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000400 */ #define ADC_CALFACT_CALFACT_D_Pos (16U) #define ADC_CALFACT_CALFACT_D_Msk (0x7FFUL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x07FF0000 */ #define ADC_CALFACT_CALFACT_D ADC_CALFACT_CALFACT_D_Msk /*!< ADC calibration factors in differential mode */ #define ADC_CALFACT_CALFACT_D_0 (0x001UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00010000 */ #define ADC_CALFACT_CALFACT_D_1 (0x002UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00020000 */ #define ADC_CALFACT_CALFACT_D_2 (0x004UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00040000 */ #define ADC_CALFACT_CALFACT_D_3 (0x008UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00080000 */ #define ADC_CALFACT_CALFACT_D_4 (0x010UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00100000 */ #define ADC_CALFACT_CALFACT_D_5 (0x020UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00200000 */ #define ADC_CALFACT_CALFACT_D_6 (0x040UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00400000 */ #define ADC_CALFACT_CALFACT_D_7 (0x080UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00800000 */ #define ADC_CALFACT_CALFACT_D_8 (0x100UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x01000000 */ #define ADC_CALFACT_CALFACT_D_9 (0x200UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x02000000 */ #define ADC_CALFACT_CALFACT_D_10 (0x400UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x04000000 */ /******************** Bit definition for ADC_CALFACT2 register ********************/ #define ADC_CALFACT2_LINCALFACT_Pos (0U) #define ADC_CALFACT2_LINCALFACT_Msk (0x3FFFFFFFUL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x3FFFFFFF */ #define ADC_CALFACT2_LINCALFACT ADC_CALFACT2_LINCALFACT_Msk /*!< ADC Linearity calibration factors */ #define ADC_CALFACT2_LINCALFACT_0 (0x00000001UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00000001 */ #define ADC_CALFACT2_LINCALFACT_1 (0x00000002UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00000002 */ #define ADC_CALFACT2_LINCALFACT_2 (0x00000004UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00000004 */ #define ADC_CALFACT2_LINCALFACT_3 (0x00000008UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00000008 */ #define ADC_CALFACT2_LINCALFACT_4 (0x00000010UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00000010 */ #define ADC_CALFACT2_LINCALFACT_5 (0x00000020UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00000020 */ #define ADC_CALFACT2_LINCALFACT_6 (0x00000040UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00000040 */ #define ADC_CALFACT2_LINCALFACT_7 (0x00000080UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00000080 */ #define ADC_CALFACT2_LINCALFACT_8 (0x00000100UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00000100 */ #define ADC_CALFACT2_LINCALFACT_9 (0x00000200UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00000200 */ #define ADC_CALFACT2_LINCALFACT_10 (0x00000400UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00000400 */ #define ADC_CALFACT2_LINCALFACT_11 (0x00000800UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00000800 */ #define ADC_CALFACT2_LINCALFACT_12 (0x00001000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00001000 */ #define ADC_CALFACT2_LINCALFACT_13 (0x00002000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00002000 */ #define ADC_CALFACT2_LINCALFACT_14 (0x00004000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00004000 */ #define ADC_CALFACT2_LINCALFACT_15 (0x00008000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00008000 */ #define ADC_CALFACT2_LINCALFACT_16 (0x00010000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00010000 */ #define ADC_CALFACT2_LINCALFACT_17 (0x00020000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00020000 */ #define ADC_CALFACT2_LINCALFACT_18 (0x00040000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00040000 */ #define ADC_CALFACT2_LINCALFACT_19 (0x00080000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00080000 */ #define ADC_CALFACT2_LINCALFACT_20 (0x00100000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00100000 */ #define ADC_CALFACT2_LINCALFACT_21 (0x00200000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00200000 */ #define ADC_CALFACT2_LINCALFACT_22 (0x00400000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00400000 */ #define ADC_CALFACT2_LINCALFACT_23 (0x00800000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x00800000 */ #define ADC_CALFACT2_LINCALFACT_24 (0x01000000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x01000000 */ #define ADC_CALFACT2_LINCALFACT_25 (0x02000000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x02000000 */ #define ADC_CALFACT2_LINCALFACT_26 (0x04000000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x04000000 */ #define ADC_CALFACT2_LINCALFACT_27 (0x08000000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x08000000 */ #define ADC_CALFACT2_LINCALFACT_28 (0x10000000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x10000000 */ #define ADC_CALFACT2_LINCALFACT_29 (0x20000000UL << ADC_CALFACT2_LINCALFACT_Pos) /*!< 0x20000000 */ /************************* ADC Common registers *****************************/ /******************** Bit definition for ADC_CSR register ********************/ #define ADC_CSR_ADRDY_MST_Pos (0U) #define ADC_CSR_ADRDY_MST_Msk (0x1UL << ADC_CSR_ADRDY_MST_Pos) /*!< 0x00000001 */ #define ADC_CSR_ADRDY_MST ADC_CSR_ADRDY_MST_Msk /*!< Master ADC ready */ #define ADC_CSR_EOSMP_MST_Pos (1U) #define ADC_CSR_EOSMP_MST_Msk (0x1UL << ADC_CSR_EOSMP_MST_Pos) /*!< 0x00000002 */ #define ADC_CSR_EOSMP_MST ADC_CSR_EOSMP_MST_Msk /*!< End of sampling phase flag of the master ADC */ #define ADC_CSR_EOC_MST_Pos (2U) #define ADC_CSR_EOC_MST_Msk (0x1UL << ADC_CSR_EOC_MST_Pos) /*!< 0x00000004 */ #define ADC_CSR_EOC_MST ADC_CSR_EOC_MST_Msk /*!< End of regular conversion of the master ADC */ #define ADC_CSR_EOS_MST_Pos (3U) #define ADC_CSR_EOS_MST_Msk (0x1UL << ADC_CSR_EOS_MST_Pos) /*!< 0x00000008 */ #define ADC_CSR_EOS_MST ADC_CSR_EOS_MST_Msk /*!< End of regular sequence flag of the master ADC */ #define ADC_CSR_OVR_MST_Pos (4U) #define ADC_CSR_OVR_MST_Msk (0x1UL << ADC_CSR_OVR_MST_Pos) /*!< 0x00000010 */ #define ADC_CSR_OVR_MST ADC_CSR_OVR_MST_Msk /*!< Overrun flag of the master ADC */ #define ADC_CSR_JEOC_MST_Pos (5U) #define ADC_CSR_JEOC_MST_Msk (0x1UL << ADC_CSR_JEOC_MST_Pos) /*!< 0x00000020 */ #define ADC_CSR_JEOC_MST ADC_CSR_JEOC_MST_Msk /*!< End of injected conversion of the master ADC */ #define ADC_CSR_JEOS_MST_Pos (6U) #define ADC_CSR_JEOS_MST_Msk (0x1UL << ADC_CSR_JEOS_MST_Pos) /*!< 0x00000040 */ #define ADC_CSR_JEOS_MST ADC_CSR_JEOS_MST_Msk /*!< End of injected sequence flag of the master ADC */ #define ADC_CSR_AWD1_MST_Pos (7U) #define ADC_CSR_AWD1_MST_Msk (0x1UL << ADC_CSR_AWD1_MST_Pos) /*!< 0x00000080 */ #define ADC_CSR_AWD1_MST ADC_CSR_AWD1_MST_Msk /*!< Analog watchdog 1 flag of the master ADC */ #define ADC_CSR_AWD2_MST_Pos (8U) #define ADC_CSR_AWD2_MST_Msk (0x1UL << ADC_CSR_AWD2_MST_Pos) /*!< 0x00000100 */ #define ADC_CSR_AWD2_MST ADC_CSR_AWD2_MST_Msk /*!< Analog watchdog 2 flag of the master ADC */ #define ADC_CSR_AWD3_MST_Pos (9U) #define ADC_CSR_AWD3_MST_Msk (0x1UL << ADC_CSR_AWD3_MST_Pos) /*!< 0x00000200 */ #define ADC_CSR_AWD3_MST ADC_CSR_AWD3_MST_Msk /*!< Analog watchdog 3 flag of the master ADC */ #define ADC_CSR_JQOVF_MST_Pos (10U) #define ADC_CSR_JQOVF_MST_Msk (0x1UL << ADC_CSR_JQOVF_MST_Pos) /*!< 0x00000400 */ #define ADC_CSR_JQOVF_MST ADC_CSR_JQOVF_MST_Msk /*!< Injected context queue overflow flag of the master ADC */ #define ADC_CSR_ADRDY_SLV_Pos (16U) #define ADC_CSR_ADRDY_SLV_Msk (0x1UL << ADC_CSR_ADRDY_SLV_Pos) /*!< 0x00010000 */ #define ADC_CSR_ADRDY_SLV ADC_CSR_ADRDY_SLV_Msk /*!< Slave ADC ready */ #define ADC_CSR_EOSMP_SLV_Pos (17U) #define ADC_CSR_EOSMP_SLV_Msk (0x1UL << ADC_CSR_EOSMP_SLV_Pos) /*!< 0x00020000 */ #define ADC_CSR_EOSMP_SLV ADC_CSR_EOSMP_SLV_Msk /*!< End of sampling phase flag of the slave ADC */ #define ADC_CSR_EOC_SLV_Pos (18U) #define ADC_CSR_EOC_SLV_Msk (0x1UL << ADC_CSR_EOC_SLV_Pos) /*!< 0x00040000 */ #define ADC_CSR_EOC_SLV ADC_CSR_EOC_SLV_Msk /*!< End of regular conversion of the slave ADC */ #define ADC_CSR_EOS_SLV_Pos (19U) #define ADC_CSR_EOS_SLV_Msk (0x1UL << ADC_CSR_EOS_SLV_Pos) /*!< 0x00080000 */ #define ADC_CSR_EOS_SLV ADC_CSR_EOS_SLV_Msk /*!< End of regular sequence flag of the slave ADC */ #define ADC_CSR_OVR_SLV_Pos (20U) #define ADC_CSR_OVR_SLV_Msk (0x1UL << ADC_CSR_OVR_SLV_Pos) /*!< 0x00100000 */ #define ADC_CSR_OVR_SLV ADC_CSR_OVR_SLV_Msk /*!< Overrun flag of the slave ADC */ #define ADC_CSR_JEOC_SLV_Pos (21U) #define ADC_CSR_JEOC_SLV_Msk (0x1UL << ADC_CSR_JEOC_SLV_Pos) /*!< 0x00200000 */ #define ADC_CSR_JEOC_SLV ADC_CSR_JEOC_SLV_Msk /*!< End of injected conversion of the slave ADC */ #define ADC_CSR_JEOS_SLV_Pos (22U) #define ADC_CSR_JEOS_SLV_Msk (0x1UL << ADC_CSR_JEOS_SLV_Pos) /*!< 0x00400000 */ #define ADC_CSR_JEOS_SLV ADC_CSR_JEOS_SLV_Msk /*!< End of injected sequence flag of the slave ADC */ #define ADC_CSR_AWD1_SLV_Pos (23U) #define ADC_CSR_AWD1_SLV_Msk (0x1UL << ADC_CSR_AWD1_SLV_Pos) /*!< 0x00800000 */ #define ADC_CSR_AWD1_SLV ADC_CSR_AWD1_SLV_Msk /*!< Analog watchdog 1 flag of the slave ADC */ #define ADC_CSR_AWD2_SLV_Pos (24U) #define ADC_CSR_AWD2_SLV_Msk (0x1UL << ADC_CSR_AWD2_SLV_Pos) /*!< 0x01000000 */ #define ADC_CSR_AWD2_SLV ADC_CSR_AWD2_SLV_Msk /*!< Analog watchdog 2 flag of the slave ADC */ #define ADC_CSR_AWD3_SLV_Pos (25U) #define ADC_CSR_AWD3_SLV_Msk (0x1UL << ADC_CSR_AWD3_SLV_Pos) /*!< 0x02000000 */ #define ADC_CSR_AWD3_SLV ADC_CSR_AWD3_SLV_Msk /*!< Analog watchdog 3 flag of the slave ADC */ #define ADC_CSR_JQOVF_SLV_Pos (26U) #define ADC_CSR_JQOVF_SLV_Msk (0x1UL << ADC_CSR_JQOVF_SLV_Pos) /*!< 0x04000000 */ #define ADC_CSR_JQOVF_SLV ADC_CSR_JQOVF_SLV_Msk /*!< Injected context queue overflow flag of the slave ADC */ /******************** Bit definition for ADC_CCR register ********************/ #define ADC_CCR_DUAL_Pos (0U) #define ADC_CCR_DUAL_Msk (0x1FUL << ADC_CCR_DUAL_Pos) /*!< 0x0000001F */ #define ADC_CCR_DUAL ADC_CCR_DUAL_Msk /*!< Dual ADC mode selection */ #define ADC_CCR_DUAL_0 (0x01UL << ADC_CCR_DUAL_Pos) /*!< 0x00000001 */ #define ADC_CCR_DUAL_1 (0x02UL << ADC_CCR_DUAL_Pos) /*!< 0x00000002 */ #define ADC_CCR_DUAL_2 (0x04UL << ADC_CCR_DUAL_Pos) /*!< 0x00000004 */ #define ADC_CCR_DUAL_3 (0x08UL << ADC_CCR_DUAL_Pos) /*!< 0x00000008 */ #define ADC_CCR_DUAL_4 (0x10UL << ADC_CCR_DUAL_Pos) /*!< 0x00000010 */ #define ADC_CCR_DELAY_Pos (8U) #define ADC_CCR_DELAY_Msk (0xFUL << ADC_CCR_DELAY_Pos) /*!< 0x00000F00 */ #define ADC_CCR_DELAY ADC_CCR_DELAY_Msk /*!< Delay between 2 sampling phases */ #define ADC_CCR_DELAY_0 (0x1UL << ADC_CCR_DELAY_Pos) /*!< 0x00000100 */ #define ADC_CCR_DELAY_1 (0x2UL << ADC_CCR_DELAY_Pos) /*!< 0x00000200 */ #define ADC_CCR_DELAY_2 (0x4UL << ADC_CCR_DELAY_Pos) /*!< 0x00000400 */ #define ADC_CCR_DELAY_3 (0x8UL << ADC_CCR_DELAY_Pos) /*!< 0x00000800 */ #define ADC_CCR_DAMDF_Pos (14U) #define ADC_CCR_DAMDF_Msk (0x3UL << ADC_CCR_DAMDF_Pos) /*!< 0x0000C000 */ #define ADC_CCR_DAMDF ADC_CCR_DAMDF_Msk /*!< Dual ADC mode Data format */ #define ADC_CCR_DAMDF_0 (0x1UL << ADC_CCR_DAMDF_Pos) /*!< 0x00004000 */ #define ADC_CCR_DAMDF_1 (0x2UL << ADC_CCR_DAMDF_Pos) /*!< 0x00008000 */ #define ADC_CCR_CKMODE_Pos (16U) #define ADC_CCR_CKMODE_Msk (0x3UL << ADC_CCR_CKMODE_Pos) /*!< 0x00030000 */ #define ADC_CCR_CKMODE ADC_CCR_CKMODE_Msk /*!< ADC clock mode */ #define ADC_CCR_CKMODE_0 (0x1UL << ADC_CCR_CKMODE_Pos) /*!< 0x00010000 */ #define ADC_CCR_CKMODE_1 (0x2UL << ADC_CCR_CKMODE_Pos) /*!< 0x00020000 */ #define ADC_CCR_PRESC_Pos (18U) #define ADC_CCR_PRESC_Msk (0xFUL << ADC_CCR_PRESC_Pos) /*!< 0x003C0000 */ #define ADC_CCR_PRESC ADC_CCR_PRESC_Msk /*!< ADC prescaler */ #define ADC_CCR_PRESC_0 (0x1UL << ADC_CCR_PRESC_Pos) /*!< 0x00040000 */ #define ADC_CCR_PRESC_1 (0x2UL << ADC_CCR_PRESC_Pos) /*!< 0x00080000 */ #define ADC_CCR_PRESC_2 (0x4UL << ADC_CCR_PRESC_Pos) /*!< 0x00100000 */ #define ADC_CCR_PRESC_3 (0x8UL << ADC_CCR_PRESC_Pos) /*!< 0x00200000 */ #define ADC_CCR_VREFEN_Pos (22U) #define ADC_CCR_VREFEN_Msk (0x1UL << ADC_CCR_VREFEN_Pos) /*!< 0x00400000 */ #define ADC_CCR_VREFEN ADC_CCR_VREFEN_Msk /*!< VREFINT enable */ #define ADC_CCR_TSEN_Pos (23U) #define ADC_CCR_TSEN_Msk (0x1UL << ADC_CCR_TSEN_Pos) /*!< 0x00800000 */ #define ADC_CCR_TSEN ADC_CCR_TSEN_Msk /*!< Temperature sensor enable */ #define ADC_CCR_VBATEN_Pos (24U) #define ADC_CCR_VBATEN_Msk (0x1UL << ADC_CCR_VBATEN_Pos) /*!< 0x01000000 */ #define ADC_CCR_VBATEN ADC_CCR_VBATEN_Msk /*!< VBAT enable */ /******************** Bit definition for ADC_CDR register *******************/ #define ADC_CDR_RDATA_MST_Pos (0U) #define ADC_CDR_RDATA_MST_Msk (0xFFFFUL << ADC_CDR_RDATA_MST_Pos) /*!< 0x0000FFFF */ #define ADC_CDR_RDATA_MST ADC_CDR_RDATA_MST_Msk /*!< ADC multimode master group regular conversion data */ #define ADC_CDR_RDATA_SLV_Pos (16U) #define ADC_CDR_RDATA_SLV_Msk (0xFFFFUL << ADC_CDR_RDATA_SLV_Pos) /*!< 0xFFFF0000 */ #define ADC_CDR_RDATA_SLV ADC_CDR_RDATA_SLV_Msk /*!< ADC multimode slave group regular conversion data */ /******************** Bit definition for ADC_CDR2 register ******************/ #define ADC_CDR2_RDATA_ALT_Pos (0U) #define ADC_CDR2_RDATA_ALT_Msk (0xFFFFFFFFUL << ADC_CDR2_RDATA_ALT_Pos) /*!< 0xFFFFFFFF */ #define ADC_CDR2_RDATA_ALT ADC_CDR2_RDATA_ALT_Msk /*!< Regular data of the master/slave alternated ADCs */ /******************************************************************************/ /* */ /* VREFBUF */ /* */ /******************************************************************************/ /******************* Bit definition for VREFBUF_CSR register ****************/ #define VREFBUF_CSR_ENVR_Pos (0U) #define VREFBUF_CSR_ENVR_Msk (0x1UL << VREFBUF_CSR_ENVR_Pos) /*!< 0x00000001 */ #define VREFBUF_CSR_ENVR VREFBUF_CSR_ENVR_Msk /*!*/ #define DAC_CR_CEN1_Pos (14U) #define DAC_CR_CEN1_Msk (0x1UL << DAC_CR_CEN1_Pos) /*!< 0x00004000 */ #define DAC_CR_CEN1 DAC_CR_CEN1_Msk /*!*/ #define DAC_CR_EN2_Pos (16U) #define DAC_CR_EN2_Msk (0x1UL << DAC_CR_EN2_Pos) /*!< 0x00010000 */ #define DAC_CR_EN2 DAC_CR_EN2_Msk /*!*/ #define DAC_CR_CEN2_Pos (30U) #define DAC_CR_CEN2_Msk (0x1UL << DAC_CR_CEN2_Pos) /*!< 0x40000000 */ #define DAC_CR_CEN2 DAC_CR_CEN2_Msk /*!*/ /***************** Bit definition for DAC_SWTRIGR register ******************/ #define DAC_SWTRIGR_SWTRIG1_Pos (0U) #define DAC_SWTRIGR_SWTRIG1_Msk (0x1UL << DAC_SWTRIGR_SWTRIG1_Pos) /*!< 0x00000001 */ #define DAC_SWTRIGR_SWTRIG1 DAC_SWTRIGR_SWTRIG1_Msk /*!> 1) /* 1 MB */ #define FLASH_SECTOR_SIZE 0x00020000UL /* 128 KB */ #define FLASH_LATENCY_DEFAULT FLASH_ACR_LATENCY_7WS /* FLASH Seven Latency cycles */ #define FLASH_NB_32BITWORD_IN_FLASHWORD 8U /* 256 bits */ #define DUAL_BANK /* Dual-bank Flash */ /******************* Bits definition for FLASH_ACR register **********************/ #define FLASH_ACR_LATENCY_Pos (0U) #define FLASH_ACR_LATENCY_Msk (0xFUL << FLASH_ACR_LATENCY_Pos) /*!< 0x0000000F: bit4 is kept only for legacy purpose */ #define FLASH_ACR_LATENCY FLASH_ACR_LATENCY_Msk /*!< Read Latency */ #define FLASH_ACR_LATENCY_0WS (0x00000000UL) #define FLASH_ACR_LATENCY_1WS (0x00000001UL) #define FLASH_ACR_LATENCY_2WS (0x00000002UL) #define FLASH_ACR_LATENCY_3WS (0x00000003UL) #define FLASH_ACR_LATENCY_4WS (0x00000004UL) #define FLASH_ACR_LATENCY_5WS (0x00000005UL) #define FLASH_ACR_LATENCY_6WS (0x00000006UL) #define FLASH_ACR_LATENCY_7WS (0x00000007UL) #define FLASH_ACR_WRHIGHFREQ_Pos (4U) #define FLASH_ACR_WRHIGHFREQ_Msk (0x3UL << FLASH_ACR_WRHIGHFREQ_Pos) /*!< 0x00000030 */ #define FLASH_ACR_WRHIGHFREQ FLASH_ACR_WRHIGHFREQ_Msk /*!< Flash signal delay */ #define FLASH_ACR_WRHIGHFREQ_0 (0x1UL << FLASH_ACR_WRHIGHFREQ_Pos) /*!< 0x00000010 */ #define FLASH_ACR_WRHIGHFREQ_1 (0x2UL << FLASH_ACR_WRHIGHFREQ_Pos) /*!< 0x00000020 */ /* Legacy FLASH Latency defines */ #define FLASH_ACR_LATENCY_8WS (0x00000008UL) #define FLASH_ACR_LATENCY_9WS (0x00000009UL) #define FLASH_ACR_LATENCY_10WS (0x0000000AUL) #define FLASH_ACR_LATENCY_11WS (0x0000000BUL) #define FLASH_ACR_LATENCY_12WS (0x0000000CUL) #define FLASH_ACR_LATENCY_13WS (0x0000000DUL) #define FLASH_ACR_LATENCY_14WS (0x0000000EUL) #define FLASH_ACR_LATENCY_15WS (0x0000000FUL) /******************* Bits definition for FLASH_CR register ***********************/ #define FLASH_CR_LOCK_Pos (0U) #define FLASH_CR_LOCK_Msk (0x1UL << FLASH_CR_LOCK_Pos) /*!< 0x00000001 */ #define FLASH_CR_LOCK FLASH_CR_LOCK_Msk /*!< Configuration lock bit */ #define FLASH_CR_PG_Pos (1U) #define FLASH_CR_PG_Msk (0x1UL << FLASH_CR_PG_Pos) /*!< 0x00000002 */ #define FLASH_CR_PG FLASH_CR_PG_Msk /*!< Internal buffer control bit */ #define FLASH_CR_SER_Pos (2U) #define FLASH_CR_SER_Msk (0x1UL << FLASH_CR_SER_Pos) /*!< 0x00000004 */ #define FLASH_CR_SER FLASH_CR_SER_Msk /*!< Sector erase request */ #define FLASH_CR_BER_Pos (3U) #define FLASH_CR_BER_Msk (0x1UL << FLASH_CR_BER_Pos) /*!< 0x00000008 */ #define FLASH_CR_BER FLASH_CR_BER_Msk /*!< Bank erase request */ #define FLASH_CR_PSIZE_Pos (4U) #define FLASH_CR_PSIZE_Msk (0x3UL << FLASH_CR_PSIZE_Pos) /*!< 0x00000030 */ #define FLASH_CR_PSIZE FLASH_CR_PSIZE_Msk /*!< Program size */ #define FLASH_CR_PSIZE_0 (0x1UL << FLASH_CR_PSIZE_Pos) /*!< 0x00000010 */ #define FLASH_CR_PSIZE_1 (0x2UL << FLASH_CR_PSIZE_Pos) /*!< 0x00000020 */ #define FLASH_CR_FW_Pos (6U) #define FLASH_CR_FW_Msk (0x1UL << FLASH_CR_FW_Pos) /*!< 0x00000040 */ #define FLASH_CR_FW FLASH_CR_FW_Msk /*!< Write forcing control bit */ #define FLASH_CR_START_Pos (7U) #define FLASH_CR_START_Msk (0x1UL << FLASH_CR_START_Pos) /*!< 0x00000080 */ #define FLASH_CR_START FLASH_CR_START_Msk /*!< Erase start control bit */ #define FLASH_CR_SNB_Pos (8U) #define FLASH_CR_SNB_Msk (0x7UL << FLASH_CR_SNB_Pos) /*!< 0x00000700 */ #define FLASH_CR_SNB FLASH_CR_SNB_Msk /*!< Sector erase selection number */ #define FLASH_CR_SNB_0 (0x1UL << FLASH_CR_SNB_Pos) /*!< 0x00000100 */ #define FLASH_CR_SNB_1 (0x2UL << FLASH_CR_SNB_Pos) /*!< 0x00000200 */ #define FLASH_CR_SNB_2 (0x4UL << FLASH_CR_SNB_Pos) /*!< 0x00000400 */ #define FLASH_CR_CRC_EN_Pos (15U) #define FLASH_CR_CRC_EN_Msk (0x1UL << FLASH_CR_CRC_EN_Pos) /*!< 0x00008000 */ #define FLASH_CR_CRC_EN FLASH_CR_CRC_EN_Msk /*!< CRC control bit */ #define FLASH_CR_EOPIE_Pos (16U) #define FLASH_CR_EOPIE_Msk (0x1UL << FLASH_CR_EOPIE_Pos) /*!< 0x00010000 */ #define FLASH_CR_EOPIE FLASH_CR_EOPIE_Msk /*!< End-of-program interrupt control bit */ #define FLASH_CR_WRPERRIE_Pos (17U) #define FLASH_CR_WRPERRIE_Msk (0x1UL << FLASH_CR_WRPERRIE_Pos) /*!< 0x00020000 */ #define FLASH_CR_WRPERRIE FLASH_CR_WRPERRIE_Msk /*!< Write protection error interrupt enable bit */ #define FLASH_CR_PGSERRIE_Pos (18U) #define FLASH_CR_PGSERRIE_Msk (0x1UL << FLASH_CR_PGSERRIE_Pos) /*!< 0x00040000 */ #define FLASH_CR_PGSERRIE FLASH_CR_PGSERRIE_Msk /*!< Programming sequence error interrupt enable bit */ #define FLASH_CR_STRBERRIE_Pos (19U) #define FLASH_CR_STRBERRIE_Msk (0x1UL << FLASH_CR_STRBERRIE_Pos) /*!< 0x00080000 */ #define FLASH_CR_STRBERRIE FLASH_CR_STRBERRIE_Msk /*!< Strobe error interrupt enable bit */ #define FLASH_CR_INCERRIE_Pos (21U) #define FLASH_CR_INCERRIE_Msk (0x1UL << FLASH_CR_INCERRIE_Pos) /*!< 0x00200000 */ #define FLASH_CR_INCERRIE FLASH_CR_INCERRIE_Msk /*!< Inconsistency error interrupt enable bit */ #define FLASH_CR_OPERRIE_Pos (22U) #define FLASH_CR_OPERRIE_Msk (0x1UL << FLASH_CR_OPERRIE_Pos) /*!< 0x00400000 */ #define FLASH_CR_OPERRIE FLASH_CR_OPERRIE_Msk /*!< Write/erase error interrupt enable bit */ #define FLASH_CR_RDPERRIE_Pos (23U) #define FLASH_CR_RDPERRIE_Msk (0x1UL << FLASH_CR_RDPERRIE_Pos) /*!< 0x00800000 */ #define FLASH_CR_RDPERRIE FLASH_CR_RDPERRIE_Msk /*!< Read protection error interrupt enable bit */ #define FLASH_CR_RDSERRIE_Pos (24U) #define FLASH_CR_RDSERRIE_Msk (0x1UL << FLASH_CR_RDSERRIE_Pos) /*!< 0x01000000 */ #define FLASH_CR_RDSERRIE FLASH_CR_RDSERRIE_Msk /*!< Secure error interrupt enable bit */ #define FLASH_CR_SNECCERRIE_Pos (25U) #define FLASH_CR_SNECCERRIE_Msk (0x1UL << FLASH_CR_SNECCERRIE_Pos) /*!< 0x02000000 */ #define FLASH_CR_SNECCERRIE FLASH_CR_SNECCERRIE_Msk /*!< ECC single correction error interrupt enable bit */ #define FLASH_CR_DBECCERRIE_Pos (26U) #define FLASH_CR_DBECCERRIE_Msk (0x1UL << FLASH_CR_DBECCERRIE_Pos) /*!< 0x04000000 */ #define FLASH_CR_DBECCERRIE FLASH_CR_DBECCERRIE_Msk /*!< ECC double detection error interrupt enable bit */ #define FLASH_CR_CRCENDIE_Pos (27U) #define FLASH_CR_CRCENDIE_Msk (0x1UL << FLASH_CR_CRCENDIE_Pos) /*!< 0x08000000 */ #define FLASH_CR_CRCENDIE FLASH_CR_CRCENDIE_Msk /*!< CRC end of calculation interrupt enable bit */ #define FLASH_CR_CRCRDERRIE_Pos (28U) #define FLASH_CR_CRCRDERRIE_Msk (0x1UL << FLASH_CR_CRCRDERRIE_Pos) /*!< 0x10000000 */ #define FLASH_CR_CRCRDERRIE FLASH_CR_CRCRDERRIE_Msk /*!< CRC read error interrupt enable bit */ /******************* Bits definition for FLASH_SR register ***********************/ #define FLASH_SR_BSY_Pos (0U) #define FLASH_SR_BSY_Msk (0x1UL << FLASH_SR_BSY_Pos) /*!< 0x00000001 */ #define FLASH_SR_BSY FLASH_SR_BSY_Msk /*!< Busy flag */ #define FLASH_SR_WBNE_Pos (1U) #define FLASH_SR_WBNE_Msk (0x1UL << FLASH_SR_WBNE_Pos) /*!< 0x00000002 */ #define FLASH_SR_WBNE FLASH_SR_WBNE_Msk /*!< Write buffer not empty flag */ #define FLASH_SR_QW_Pos (2U) #define FLASH_SR_QW_Msk (0x1UL << FLASH_SR_QW_Pos) /*!< 0x00000004 */ #define FLASH_SR_QW FLASH_SR_QW_Msk /*!< Wait queue flag */ #define FLASH_SR_CRC_BUSY_Pos (3U) #define FLASH_SR_CRC_BUSY_Msk (0x1UL << FLASH_SR_CRC_BUSY_Pos) /*!< 0x00000008 */ #define FLASH_SR_CRC_BUSY FLASH_SR_CRC_BUSY_Msk /*!< CRC busy flag */ #define FLASH_SR_EOP_Pos (16U) #define FLASH_SR_EOP_Msk (0x1UL << FLASH_SR_EOP_Pos) /*!< 0x00010000 */ #define FLASH_SR_EOP FLASH_SR_EOP_Msk /*!< End-of-program flag */ #define FLASH_SR_WRPERR_Pos (17U) #define FLASH_SR_WRPERR_Msk (0x1UL << FLASH_SR_WRPERR_Pos) /*!< 0x00020000 */ #define FLASH_SR_WRPERR FLASH_SR_WRPERR_Msk /*!< Write protection error flag */ #define FLASH_SR_PGSERR_Pos (18U) #define FLASH_SR_PGSERR_Msk (0x1UL << FLASH_SR_PGSERR_Pos) /*!< 0x00040000 */ #define FLASH_SR_PGSERR FLASH_SR_PGSERR_Msk /*!< Programming sequence error flag */ #define FLASH_SR_STRBERR_Pos (19U) #define FLASH_SR_STRBERR_Msk (0x1UL << FLASH_SR_STRBERR_Pos) /*!< 0x00080000 */ #define FLASH_SR_STRBERR FLASH_SR_STRBERR_Msk /*!< Strobe error flag */ #define FLASH_SR_INCERR_Pos (21U) #define FLASH_SR_INCERR_Msk (0x1UL << FLASH_SR_INCERR_Pos) /*!< 0x00200000 */ #define FLASH_SR_INCERR FLASH_SR_INCERR_Msk /*!< Inconsistency error flag */ #define FLASH_SR_OPERR_Pos (22U) #define FLASH_SR_OPERR_Msk (0x1UL << FLASH_SR_OPERR_Pos) /*!< 0x00400000 */ #define FLASH_SR_OPERR FLASH_SR_OPERR_Msk /*!< Write/erase error flag */ #define FLASH_SR_RDPERR_Pos (23U) #define FLASH_SR_RDPERR_Msk (0x1UL << FLASH_SR_RDPERR_Pos) /*!< 0x00800000 */ #define FLASH_SR_RDPERR FLASH_SR_RDPERR_Msk /*!< Read protection error flag */ #define FLASH_SR_RDSERR_Pos (24U) #define FLASH_SR_RDSERR_Msk (0x1UL << FLASH_SR_RDSERR_Pos) /*!< 0x01000000 */ #define FLASH_SR_RDSERR FLASH_SR_RDSERR_Msk /*!< Secure error flag */ #define FLASH_SR_SNECCERR_Pos (25U) #define FLASH_SR_SNECCERR_Msk (0x1UL << FLASH_SR_SNECCERR_Pos) /*!< 0x02000000 */ #define FLASH_SR_SNECCERR FLASH_SR_SNECCERR_Msk /*!< Single correction error flag */ #define FLASH_SR_DBECCERR_Pos (26U) #define FLASH_SR_DBECCERR_Msk (0x1UL << FLASH_SR_DBECCERR_Pos) /*!< 0x04000000 */ #define FLASH_SR_DBECCERR FLASH_SR_DBECCERR_Msk /*!< ECC double detection error flag */ #define FLASH_SR_CRCEND_Pos (27U) #define FLASH_SR_CRCEND_Msk (0x1UL << FLASH_SR_CRCEND_Pos) /*!< 0x08000000 */ #define FLASH_SR_CRCEND FLASH_SR_CRCEND_Msk /*!< CRC end of calculation flag */ #define FLASH_SR_CRCRDERR_Pos (28U) #define FLASH_SR_CRCRDERR_Msk (0x1UL << FLASH_SR_CRCRDERR_Pos) /*!< 0x10000000 */ #define FLASH_SR_CRCRDERR FLASH_SR_CRCRDERR_Msk /*!< CRC read error flag */ /******************* Bits definition for FLASH_CCR register *******************/ #define FLASH_CCR_CLR_EOP_Pos (16U) #define FLASH_CCR_CLR_EOP_Msk (0x1UL << FLASH_CCR_CLR_EOP_Pos) /*!< 0x00010000 */ #define FLASH_CCR_CLR_EOP FLASH_CCR_CLR_EOP_Msk /*!< EOP flag clear bit */ #define FLASH_CCR_CLR_WRPERR_Pos (17U) #define FLASH_CCR_CLR_WRPERR_Msk (0x1UL << FLASH_CCR_CLR_WRPERR_Pos) /*!< 0x00020000 */ #define FLASH_CCR_CLR_WRPERR FLASH_CCR_CLR_WRPERR_Msk /*!< WRPERR flag clear bit */ #define FLASH_CCR_CLR_PGSERR_Pos (18U) #define FLASH_CCR_CLR_PGSERR_Msk (0x1UL << FLASH_CCR_CLR_PGSERR_Pos) /*!< 0x00040000 */ #define FLASH_CCR_CLR_PGSERR FLASH_CCR_CLR_PGSERR_Msk /*!< PGSERR flag clear bit */ #define FLASH_CCR_CLR_STRBERR_Pos (19U) #define FLASH_CCR_CLR_STRBERR_Msk (0x1UL << FLASH_CCR_CLR_STRBERR_Pos) /*!< 0x00080000 */ #define FLASH_CCR_CLR_STRBERR FLASH_CCR_CLR_STRBERR_Msk /*!< STRBERR flag clear bit */ #define FLASH_CCR_CLR_INCERR_Pos (21U) #define FLASH_CCR_CLR_INCERR_Msk (0x1UL << FLASH_CCR_CLR_INCERR_Pos) /*!< 0x00200000 */ #define FLASH_CCR_CLR_INCERR FLASH_CCR_CLR_INCERR_Msk /*!< INCERR flag clear bit */ #define FLASH_CCR_CLR_OPERR_Pos (22U) #define FLASH_CCR_CLR_OPERR_Msk (0x1UL << FLASH_CCR_CLR_OPERR_Pos) /*!< 0x00400000 */ #define FLASH_CCR_CLR_OPERR FLASH_CCR_CLR_OPERR_Msk /*!< OPERR flag clear bit */ #define FLASH_CCR_CLR_RDPERR_Pos (23U) #define FLASH_CCR_CLR_RDPERR_Msk (0x1UL << FLASH_CCR_CLR_RDPERR_Pos) /*!< 0x00800000 */ #define FLASH_CCR_CLR_RDPERR FLASH_CCR_CLR_RDPERR_Msk /*!< RDPERR flag clear bit */ #define FLASH_CCR_CLR_RDSERR_Pos (24U) #define FLASH_CCR_CLR_RDSERR_Msk (0x1UL << FLASH_CCR_CLR_RDSERR_Pos) /*!< 0x01000000 */ #define FLASH_CCR_CLR_RDSERR FLASH_CCR_CLR_RDSERR_Msk /*!< RDSERR flag clear bit */ #define FLASH_CCR_CLR_SNECCERR_Pos (25U) #define FLASH_CCR_CLR_SNECCERR_Msk (0x1UL << FLASH_CCR_CLR_SNECCERR_Pos) /*!< 0x02000000 */ #define FLASH_CCR_CLR_SNECCERR FLASH_CCR_CLR_SNECCERR_Msk /*!< SNECCERR flag clear bit */ #define FLASH_CCR_CLR_DBECCERR_Pos (26U) #define FLASH_CCR_CLR_DBECCERR_Msk (0x1UL << FLASH_CCR_CLR_DBECCERR_Pos) /*!< 0x04000000 */ #define FLASH_CCR_CLR_DBECCERR FLASH_CCR_CLR_DBECCERR_Msk /*!< DBECCERR flag clear bit */ #define FLASH_CCR_CLR_CRCEND_Pos (27U) #define FLASH_CCR_CLR_CRCEND_Msk (0x1UL << FLASH_CCR_CLR_CRCEND_Pos) /*!< 0x08000000 */ #define FLASH_CCR_CLR_CRCEND FLASH_CCR_CLR_CRCEND_Msk /*!< CRCEND flag clear bit */ #define FLASH_CCR_CLR_CRCRDERR_Pos (28U) #define FLASH_CCR_CLR_CRCRDERR_Msk (0x1UL << FLASH_CCR_CLR_CRCRDERR_Pos) /*!< 0x10000000 */ #define FLASH_CCR_CLR_CRCRDERR FLASH_CCR_CLR_CRCRDERR_Msk /*!< CRCRDERR flag clear bit */ /******************* Bits definition for FLASH_OPTCR register *******************/ #define FLASH_OPTCR_OPTLOCK_Pos (0U) #define FLASH_OPTCR_OPTLOCK_Msk (0x1UL << FLASH_OPTCR_OPTLOCK_Pos) /*!< 0x00000001 */ #define FLASH_OPTCR_OPTLOCK FLASH_OPTCR_OPTLOCK_Msk /*!< FLASH_OPTCR lock option configuration bit */ #define FLASH_OPTCR_OPTSTART_Pos (1U) #define FLASH_OPTCR_OPTSTART_Msk (0x1UL << FLASH_OPTCR_OPTSTART_Pos) /*!< 0x00000002 */ #define FLASH_OPTCR_OPTSTART FLASH_OPTCR_OPTSTART_Msk /*!< Option byte start change option configuration bit */ #define FLASH_OPTCR_MER_Pos (4U) #define FLASH_OPTCR_MER_Msk (0x1UL << FLASH_OPTCR_MER_Pos) /*!< 0x00000010 */ #define FLASH_OPTCR_MER FLASH_OPTCR_MER_Msk /*!< Mass erase request */ #define FLASH_OPTCR_OPTCHANGEERRIE_Pos (30U) #define FLASH_OPTCR_OPTCHANGEERRIE_Msk (0x1UL << FLASH_OPTCR_OPTCHANGEERRIE_Pos) /*!< 0x40000000 */ #define FLASH_OPTCR_OPTCHANGEERRIE FLASH_OPTCR_OPTCHANGEERRIE_Msk /*!< Option byte change error interrupt enable bit */ #define FLASH_OPTCR_SWAP_BANK_Pos (31U) #define FLASH_OPTCR_SWAP_BANK_Msk (0x1UL << FLASH_OPTCR_SWAP_BANK_Pos) /*!< 0x80000000 */ #define FLASH_OPTCR_SWAP_BANK FLASH_OPTCR_SWAP_BANK_Msk /*!< Bank swapping option configuration bit */ /******************* Bits definition for FLASH_OPTSR register ***************/ #define FLASH_OPTSR_OPT_BUSY_Pos (0U) #define FLASH_OPTSR_OPT_BUSY_Msk (0x1UL << FLASH_OPTSR_OPT_BUSY_Pos) /*!< 0x00000001 */ #define FLASH_OPTSR_OPT_BUSY FLASH_OPTSR_OPT_BUSY_Msk /*!< Option byte change ongoing flag */ #define FLASH_OPTSR_BOR_LEV_Pos (2U) #define FLASH_OPTSR_BOR_LEV_Msk (0x3UL << FLASH_OPTSR_BOR_LEV_Pos) /*!< 0x0000000C */ #define FLASH_OPTSR_BOR_LEV FLASH_OPTSR_BOR_LEV_Msk /*!< Brownout level option status bit */ #define FLASH_OPTSR_BOR_LEV_0 (0x1UL << FLASH_OPTSR_BOR_LEV_Pos) /*!< 0x00000004 */ #define FLASH_OPTSR_BOR_LEV_1 (0x2UL << FLASH_OPTSR_BOR_LEV_Pos) /*!< 0x00000008 */ #define FLASH_OPTSR_IWDG1_SW_Pos (4U) #define FLASH_OPTSR_IWDG1_SW_Msk (0x1UL << FLASH_OPTSR_IWDG1_SW_Pos) /*!< 0x00000010 */ #define FLASH_OPTSR_IWDG1_SW FLASH_OPTSR_IWDG1_SW_Msk /*!< IWDG1 control mode option status bit */ #define FLASH_OPTSR_NRST_STOP_D1_Pos (6U) #define FLASH_OPTSR_NRST_STOP_D1_Msk (0x1UL << FLASH_OPTSR_NRST_STOP_D1_Pos) /*!< 0x00000040 */ #define FLASH_OPTSR_NRST_STOP_D1 FLASH_OPTSR_NRST_STOP_D1_Msk /*!< D1 domain DStop entry reset option status bit */ #define FLASH_OPTSR_NRST_STBY_D1_Pos (7U) #define FLASH_OPTSR_NRST_STBY_D1_Msk (0x1UL << FLASH_OPTSR_NRST_STBY_D1_Pos) /*!< 0x00000080 */ #define FLASH_OPTSR_NRST_STBY_D1 FLASH_OPTSR_NRST_STBY_D1_Msk /*!< D1 domain DStandby entry reset option status bit */ #define FLASH_OPTSR_RDP_Pos (8U) #define FLASH_OPTSR_RDP_Msk (0xFFUL << FLASH_OPTSR_RDP_Pos) /*!< 0x0000FF00 */ #define FLASH_OPTSR_RDP FLASH_OPTSR_RDP_Msk /*!< Readout protection level option status byte */ #define FLASH_OPTSR_FZ_IWDG_STOP_Pos (17U) #define FLASH_OPTSR_FZ_IWDG_STOP_Msk (0x1UL << FLASH_OPTSR_FZ_IWDG_STOP_Pos) /*!< 0x00020000 */ #define FLASH_OPTSR_FZ_IWDG_STOP FLASH_OPTSR_FZ_IWDG_STOP_Msk /*!< IWDG Stop mode freeze option status bit */ #define FLASH_OPTSR_FZ_IWDG_SDBY_Pos (18U) #define FLASH_OPTSR_FZ_IWDG_SDBY_Msk (0x1UL << FLASH_OPTSR_FZ_IWDG_SDBY_Pos) /*!< 0x00040000 */ #define FLASH_OPTSR_FZ_IWDG_SDBY FLASH_OPTSR_FZ_IWDG_SDBY_Msk /*!< IWDG Standby mode freeze option status bit */ #define FLASH_OPTSR_ST_RAM_SIZE_Pos (19U) #define FLASH_OPTSR_ST_RAM_SIZE_Msk (0x3UL << FLASH_OPTSR_ST_RAM_SIZE_Pos) /*!< 0x00180000 */ #define FLASH_OPTSR_ST_RAM_SIZE FLASH_OPTSR_ST_RAM_SIZE_Msk /*!< ST RAM size option status */ #define FLASH_OPTSR_ST_RAM_SIZE_0 (0x1UL << FLASH_OPTSR_ST_RAM_SIZE_Pos) /*!< 0x00080000 */ #define FLASH_OPTSR_ST_RAM_SIZE_1 (0x2UL << FLASH_OPTSR_ST_RAM_SIZE_Pos) /*!< 0x00100000 */ #define FLASH_OPTSR_SECURITY_Pos (21U) #define FLASH_OPTSR_SECURITY_Msk (0x1UL << FLASH_OPTSR_SECURITY_Pos) /*!< 0x00200000 */ #define FLASH_OPTSR_SECURITY FLASH_OPTSR_SECURITY_Msk /*!< Security enable option status bit */ #define FLASH_OPTSR_IO_HSLV_Pos (29U) #define FLASH_OPTSR_IO_HSLV_Msk (0x1UL << FLASH_OPTSR_IO_HSLV_Pos) /*!< 0x20000000 */ #define FLASH_OPTSR_IO_HSLV FLASH_OPTSR_IO_HSLV_Msk /*!< I/O high-speed at low-voltage status bit */ #define FLASH_OPTSR_OPTCHANGEERR_Pos (30U) #define FLASH_OPTSR_OPTCHANGEERR_Msk (0x1UL << FLASH_OPTSR_OPTCHANGEERR_Pos) /*!< 0x40000000 */ #define FLASH_OPTSR_OPTCHANGEERR FLASH_OPTSR_OPTCHANGEERR_Msk /*!< Option byte change error flag */ #define FLASH_OPTSR_SWAP_BANK_OPT_Pos (31U) #define FLASH_OPTSR_SWAP_BANK_OPT_Msk (0x1UL << FLASH_OPTSR_SWAP_BANK_OPT_Pos) /*!< 0x80000000 */ #define FLASH_OPTSR_SWAP_BANK_OPT FLASH_OPTSR_SWAP_BANK_OPT_Msk /*!< Bank swapping option status bit */ /******************* Bits definition for FLASH_OPTCCR register *******************/ #define FLASH_OPTCCR_CLR_OPTCHANGEERR_Pos (30U) #define FLASH_OPTCCR_CLR_OPTCHANGEERR_Msk (0x1UL << FLASH_OPTCCR_CLR_OPTCHANGEERR_Pos) /*!< 0x40000000 */ #define FLASH_OPTCCR_CLR_OPTCHANGEERR FLASH_OPTCCR_CLR_OPTCHANGEERR_Msk /*!< OPTCHANGEERR reset bit */ /******************* Bits definition for FLASH_PRAR register *********************/ #define FLASH_PRAR_PROT_AREA_START_Pos (0U) #define FLASH_PRAR_PROT_AREA_START_Msk (0xFFFUL << FLASH_PRAR_PROT_AREA_START_Pos) /*!< 0x00000FFF */ #define FLASH_PRAR_PROT_AREA_START FLASH_PRAR_PROT_AREA_START_Msk /*!< PCROP area start status bits */ #define FLASH_PRAR_PROT_AREA_END_Pos (16U) #define FLASH_PRAR_PROT_AREA_END_Msk (0xFFFUL << FLASH_PRAR_PROT_AREA_END_Pos) /*!< 0x0FFF0000 */ #define FLASH_PRAR_PROT_AREA_END FLASH_PRAR_PROT_AREA_END_Msk /*!< PCROP area end status bits */ #define FLASH_PRAR_DMEP_Pos (31U) #define FLASH_PRAR_DMEP_Msk (0x1UL << FLASH_PRAR_DMEP_Pos) /*!< 0x80000000 */ #define FLASH_PRAR_DMEP FLASH_PRAR_DMEP_Msk /*!< PCROP protected erase enable option status bit */ /******************* Bits definition for FLASH_SCAR register *********************/ #define FLASH_SCAR_SEC_AREA_START_Pos (0U) #define FLASH_SCAR_SEC_AREA_START_Msk (0xFFFUL << FLASH_SCAR_SEC_AREA_START_Pos) /*!< 0x00000FFF */ #define FLASH_SCAR_SEC_AREA_START FLASH_SCAR_SEC_AREA_START_Msk /*!< Secure-only area start status bits */ #define FLASH_SCAR_SEC_AREA_END_Pos (16U) #define FLASH_SCAR_SEC_AREA_END_Msk (0xFFFUL << FLASH_SCAR_SEC_AREA_END_Pos) /*!< 0x0FFF0000 */ #define FLASH_SCAR_SEC_AREA_END FLASH_SCAR_SEC_AREA_END_Msk /*!< Secure-only area end status bits */ #define FLASH_SCAR_DMES_Pos (31U) #define FLASH_SCAR_DMES_Msk (0x1UL << FLASH_SCAR_DMES_Pos) /*!< 0x80000000 */ #define FLASH_SCAR_DMES FLASH_SCAR_DMES_Msk /*!< Secure access protected erase enable option status bit */ /******************* Bits definition for FLASH_WPSN register *********************/ #define FLASH_WPSN_WRPSN_Pos (0U) #define FLASH_WPSN_WRPSN_Msk (0xFFUL << FLASH_WPSN_WRPSN_Pos) /*!< 0x000000FF */ #define FLASH_WPSN_WRPSN FLASH_WPSN_WRPSN_Msk /*!< Sector write protection option status byte */ /******************* Bits definition for FLASH_BOOT_CUR register ****************/ #define FLASH_BOOT_ADD0_Pos (0U) #define FLASH_BOOT_ADD0_Msk (0xFFFFUL << FLASH_BOOT_ADD0_Pos) /*!< 0x0000FFFF */ #define FLASH_BOOT_ADD0 FLASH_BOOT_ADD0_Msk /*!< Arm Cortex-M7 boot address 0 */ #define FLASH_BOOT_ADD1_Pos (16U) #define FLASH_BOOT_ADD1_Msk (0xFFFFUL << FLASH_BOOT_ADD1_Pos) /*!< 0xFFFF0000 */ #define FLASH_BOOT_ADD1 FLASH_BOOT_ADD1_Msk /*!< Arm Cortex-M7 boot address 1 */ /******************* Bits definition for FLASH_CRCCR register ********************/ #define FLASH_CRCCR_CRC_SECT_Pos (0U) #define FLASH_CRCCR_CRC_SECT_Msk (0x7UL << FLASH_CRCCR_CRC_SECT_Pos) /*!< 0x00000007 */ #define FLASH_CRCCR_CRC_SECT FLASH_CRCCR_CRC_SECT_Msk /*!< CRC sector number */ #define FLASH_CRCCR_CRC_BY_SECT_Pos (8U) #define FLASH_CRCCR_CRC_BY_SECT_Msk (0x1UL << FLASH_CRCCR_CRC_BY_SECT_Pos) /*!< 0x00000100 */ #define FLASH_CRCCR_CRC_BY_SECT FLASH_CRCCR_CRC_BY_SECT_Msk /*!< CRC sector mode select bit */ #define FLASH_CRCCR_ADD_SECT_Pos (9U) #define FLASH_CRCCR_ADD_SECT_Msk (0x1UL << FLASH_CRCCR_ADD_SECT_Pos) /*!< 0x00000200 */ #define FLASH_CRCCR_ADD_SECT FLASH_CRCCR_ADD_SECT_Msk /*!< CRC sector select bit */ #define FLASH_CRCCR_CLEAN_SECT_Pos (10U) #define FLASH_CRCCR_CLEAN_SECT_Msk (0x1UL << FLASH_CRCCR_CLEAN_SECT_Pos) /*!< 0x00000400 */ #define FLASH_CRCCR_CLEAN_SECT FLASH_CRCCR_CLEAN_SECT_Msk /*!< CRC sector list clear bit */ #define FLASH_CRCCR_START_CRC_Pos (16U) #define FLASH_CRCCR_START_CRC_Msk (0x1UL << FLASH_CRCCR_START_CRC_Pos) /*!< 0x00010000 */ #define FLASH_CRCCR_START_CRC FLASH_CRCCR_START_CRC_Msk /*!< CRC start bit */ #define FLASH_CRCCR_CLEAN_CRC_Pos (17U) #define FLASH_CRCCR_CLEAN_CRC_Msk (0x1UL << FLASH_CRCCR_CLEAN_CRC_Pos) /*!< 0x00020000 */ #define FLASH_CRCCR_CLEAN_CRC FLASH_CRCCR_CLEAN_CRC_Msk /*!< CRC clear bit */ #define FLASH_CRCCR_CRC_BURST_Pos (20U) #define FLASH_CRCCR_CRC_BURST_Msk (0x3UL << FLASH_CRCCR_CRC_BURST_Pos) /*!< 0x00300000 */ #define FLASH_CRCCR_CRC_BURST FLASH_CRCCR_CRC_BURST_Msk /*!< CRC burst size */ #define FLASH_CRCCR_CRC_BURST_0 (0x1UL << FLASH_CRCCR_CRC_BURST_Pos) /*!< 0x00100000 */ #define FLASH_CRCCR_CRC_BURST_1 (0x2UL << FLASH_CRCCR_CRC_BURST_Pos) /*!< 0x00200000 */ #define FLASH_CRCCR_ALL_BANK_Pos (22U) #define FLASH_CRCCR_ALL_BANK_Msk (0x1UL << FLASH_CRCCR_ALL_BANK_Pos) /*!< 0x00400000 */ #define FLASH_CRCCR_ALL_BANK FLASH_CRCCR_ALL_BANK_Msk /*!< CRC select bit */ /******************* Bits definition for FLASH_CRCSADD register ****************/ #define FLASH_CRCSADD_CRC_START_ADDR_Pos (0U) #define FLASH_CRCSADD_CRC_START_ADDR_Msk (0xFFFFFFFFUL << FLASH_CRCSADD_CRC_START_ADDR_Pos) /*!< 0xFFFFFFFF */ #define FLASH_CRCSADD_CRC_START_ADDR FLASH_CRCSADD_CRC_START_ADDR_Msk /*!< CRC start address */ /******************* Bits definition for FLASH_CRCEADD register ****************/ #define FLASH_CRCEADD_CRC_END_ADDR_Pos (0U) #define FLASH_CRCEADD_CRC_END_ADDR_Msk (0xFFFFFFFFUL << FLASH_CRCEADD_CRC_END_ADDR_Pos) /*!< 0xFFFFFFFF */ #define FLASH_CRCEADD_CRC_END_ADDR FLASH_CRCEADD_CRC_END_ADDR_Msk /*!< CRC end address */ /******************* Bits definition for FLASH_CRCDATA register ***************/ #define FLASH_CRCDATA_CRC_DATA_Pos (0U) #define FLASH_CRCDATA_CRC_DATA_Msk (0xFFFFFFFFUL << FLASH_CRCDATA_CRC_DATA_Pos) /*!< 0xFFFFFFFF */ #define FLASH_CRCDATA_CRC_DATA FLASH_CRCDATA_CRC_DATA_Msk /*!< CRC result */ /******************* Bits definition for FLASH_ECC_FA register *******************/ #define FLASH_ECC_FA_FAIL_ECC_ADDR_Pos (0U) #define FLASH_ECC_FA_FAIL_ECC_ADDR_Msk (0x7FFFUL << FLASH_ECC_FA_FAIL_ECC_ADDR_Pos) /*!< 0x00007FFF */ #define FLASH_ECC_FA_FAIL_ECC_ADDR FLASH_ECC_FA_FAIL_ECC_ADDR_Msk /*!< ECC error address */ /******************************************************************************/ /* */ /* Flexible Memory Controller */ /* */ /******************************************************************************/ /****************** Bit definition for FMC_BCR1 register *******************/ #define FMC_BCR1_CCLKEN_Pos (20U) #define FMC_BCR1_CCLKEN_Msk (0x1UL << FMC_BCR1_CCLKEN_Pos) /*!< 0x00100000 */ #define FMC_BCR1_CCLKEN FMC_BCR1_CCLKEN_Msk /*! #if !defined (HSE_VALUE) #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (CSI_VALUE) #define CSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/ #endif /* CSI_VALUE */ #if !defined (HSI_VALUE) #define HSI_VALUE ((uint32_t)64000000) /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @} */ /** @addtogroup STM32H7xx_System_Private_TypesDefinitions * @{ */ /** * @} */ /** @addtogroup STM32H7xx_System_Private_Defines * @{ */ /************************* Miscellaneous Configuration ************************/ /*!< Uncomment the following line if you need to use initialized data in D2 domain SRAM (AHB SRAM) */ /* #define DATA_IN_D2_SRAM */ /* Note: Following vector table addresses must be defined in line with linker configuration. */ /*!< Uncomment the following line if you need to relocate the vector table anywhere in FLASH BANK1 or AXI SRAM, else the vector table is kept at the automatic remap of boot address selected */ /* #define USER_VECT_TAB_ADDRESS */ #if defined(USER_VECT_TAB_ADDRESS) #if defined(DUAL_CORE) && defined(CORE_CM4) /*!< Uncomment the following line if you need to relocate your vector Table in D2 AXI SRAM else user remap will be done in FLASH BANK2. */ /* #define VECT_TAB_SRAM */ #if defined(VECT_TAB_SRAM) #define VECT_TAB_BASE_ADDRESS D2_AXISRAM_BASE /*!< Vector Table base address field. This value must be a multiple of 0x200. */ #define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ #else #define VECT_TAB_BASE_ADDRESS FLASH_BANK2_BASE /*!< Vector Table base address field. This value must be a multiple of 0x200. */ #define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ #endif /* VECT_TAB_SRAM */ #else /*!< Uncomment the following line if you need to relocate your vector Table in D1 AXI SRAM else user remap will be done in FLASH BANK1. */ /* #define VECT_TAB_SRAM */ #if defined(VECT_TAB_SRAM) #define VECT_TAB_BASE_ADDRESS D1_AXISRAM_BASE /*!< Vector Table base address field. This value must be a multiple of 0x200. */ #define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ #else #define VECT_TAB_BASE_ADDRESS FLASH_BANK1_BASE /*!< Vector Table base address field. This value must be a multiple of 0x200. */ #define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ #endif /* VECT_TAB_SRAM */ #endif /* DUAL_CORE && CORE_CM4 */ #endif /* USER_VECT_TAB_ADDRESS */ /******************************************************************************/ /** * @} */ /** @addtogroup STM32H7xx_System_Private_Macros * @{ */ /** * @} */ /** @addtogroup STM32H7xx_System_Private_Variables * @{ */ /* This variable is updated in three ways: 1) by calling CMSIS function SystemCoreClockUpdate() 2) by calling HAL API function HAL_RCC_GetHCLKFreq() 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency Note: If you use this function to configure the system clock; then there is no need to call the 2 first functions listed above, since SystemCoreClock variable is updated automatically. */ uint32_t SystemCoreClock = 64000000; uint32_t SystemD2Clock = 64000000; const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9}; /** * @} */ /** @addtogroup STM32H7xx_System_Private_FunctionPrototypes * @{ */ /** * @} */ /** @addtogroup STM32H7xx_System_Private_Functions * @{ */ /** * @brief Setup the microcontroller system * Initialize the FPU setting and vector table location * configuration. * @param None * @retval None */ void SystemInit (void) { #if defined (DATA_IN_D2_SRAM) __IO uint32_t tmpreg; #endif /* DATA_IN_D2_SRAM */ /* FPU settings ------------------------------------------------------------*/ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) SCB->CPACR |= ((3UL << (10*2))|(3UL << (11*2))); /* set CP10 and CP11 Full Access */ #endif /* Reset the RCC clock configuration to the default reset state ------------*/ /* Increasing the CPU frequency */ if(FLASH_LATENCY_DEFAULT > (READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY))) { /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, (uint32_t)(FLASH_LATENCY_DEFAULT)); } /* Set HSION bit */ RCC->CR |= RCC_CR_HSION; /* Reset CFGR register */ RCC->CFGR = 0x00000000; /* Reset HSEON, HSECSSON, CSION, HSI48ON, CSIKERON, PLL1ON, PLL2ON and PLL3ON bits */ RCC->CR &= 0xEAF6ED7FU; /* Decreasing the number of wait states because of lower CPU frequency */ if(FLASH_LATENCY_DEFAULT < (READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY))) { /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, (uint32_t)(FLASH_LATENCY_DEFAULT)); } #if defined(D3_SRAM_BASE) /* Reset D1CFGR register */ RCC->D1CFGR = 0x00000000; /* Reset D2CFGR register */ RCC->D2CFGR = 0x00000000; /* Reset D3CFGR register */ RCC->D3CFGR = 0x00000000; #else /* Reset CDCFGR1 register */ RCC->CDCFGR1 = 0x00000000; /* Reset CDCFGR2 register */ RCC->CDCFGR2 = 0x00000000; /* Reset SRDCFGR register */ RCC->SRDCFGR = 0x00000000; #endif /* Reset PLLCKSELR register */ RCC->PLLCKSELR = 0x02020200; /* Reset PLLCFGR register */ RCC->PLLCFGR = 0x01FF0000; /* Reset PLL1DIVR register */ RCC->PLL1DIVR = 0x01010280; /* Reset PLL1FRACR register */ RCC->PLL1FRACR = 0x00000000; /* Reset PLL2DIVR register */ RCC->PLL2DIVR = 0x01010280; /* Reset PLL2FRACR register */ RCC->PLL2FRACR = 0x00000000; /* Reset PLL3DIVR register */ RCC->PLL3DIVR = 0x01010280; /* Reset PLL3FRACR register */ RCC->PLL3FRACR = 0x00000000; /* Reset HSEBYP bit */ RCC->CR &= 0xFFFBFFFFU; /* Disable all interrupts */ RCC->CIER = 0x00000000; #if (STM32H7_DEV_ID == 0x450UL) /* dual core CM7 or single core line */ if((DBGMCU->IDCODE & 0xFFFF0000U) < 0x20000000U) { /* if stm32h7 revY*/ /* Change the switch matrix read issuing capability to 1 for the AXI SRAM target (Target 7) */ *((__IO uint32_t*)0x51008108) = 0x000000001U; } #endif #if defined (DATA_IN_D2_SRAM) /* in case of initialized data in D2 SRAM (AHB SRAM) , enable the D2 SRAM clock (AHB SRAM clock) */ #if defined(RCC_AHB2ENR_D2SRAM3EN) RCC->AHB2ENR |= (RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN | RCC_AHB2ENR_D2SRAM3EN); #elif defined(RCC_AHB2ENR_D2SRAM2EN) RCC->AHB2ENR |= (RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN); #else RCC->AHB2ENR |= (RCC_AHB2ENR_AHBSRAM1EN | RCC_AHB2ENR_AHBSRAM2EN); #endif /* RCC_AHB2ENR_D2SRAM3EN */ tmpreg = RCC->AHB2ENR; (void) tmpreg; #endif /* DATA_IN_D2_SRAM */ #if defined(DUAL_CORE) && defined(CORE_CM4) /* Configure the Vector Table location add offset address for cortex-M4 ------------------*/ #if defined(USER_VECT_TAB_ADDRESS) SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal D2 AXI-RAM or in Internal FLASH */ #endif /* USER_VECT_TAB_ADDRESS */ #else /* * Disable the FMC bank1 (enabled after reset). * This, prevents CPU speculation access on this bank which blocks the use of FMC during * 24us. During this time the others FMC master (such as LTDC) cannot use it! */ FMC_Bank1_R->BTCR[0] = 0x000030D2; /* Configure the Vector Table location -------------------------------------*/ #if defined(USER_VECT_TAB_ADDRESS) SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal D1 AXI-RAM or in Internal FLASH */ #endif /* USER_VECT_TAB_ADDRESS */ #endif /*DUAL_CORE && CORE_CM4*/ } /** * @brief Update SystemCoreClock variable according to Clock Register Values. * The SystemCoreClock variable contains the core clock , it can * be used by the user application to setup the SysTick timer or configure * other parameters. * * @note Each time the core clock changes, this function must be called * to update SystemCoreClock variable value. Otherwise, any configuration * based on this variable will be incorrect. * * @note - The system frequency computed by this function is not the real * frequency in the chip. It is calculated based on the predefined * constant and the selected clock source: * * - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(*) * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) * - If SYSCLK source is PLL, SystemCoreClock will contain the CSI_VALUE(*), * HSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors. * * (*) CSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value * 4 MHz) but the real value may vary depending on the variations * in voltage and temperature. * (**) HSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value * 64 MHz) but the real value may vary depending on the variations * in voltage and temperature. * * (***)HSE_VALUE is a constant defined in stm32h7xx_hal.h file (default value * 25 MHz), user has to ensure that HSE_VALUE is same as the real * frequency of the crystal used. Otherwise, this function may * have wrong result. * * - The result of this function could be not correct when using fractional * value for HSE crystal. * @param None * @retval None */ void SystemCoreClockUpdate (void) { uint32_t pllp, pllsource, pllm, pllfracen, hsivalue, tmp; uint32_t common_system_clock; float_t fracn1, pllvco; /* Get SYSCLK source -------------------------------------------------------*/ switch (RCC->CFGR & RCC_CFGR_SWS) { case RCC_CFGR_SWS_HSI: /* HSI used as system clock source */ common_system_clock = (uint32_t) (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)); break; case RCC_CFGR_SWS_CSI: /* CSI used as system clock source */ common_system_clock = CSI_VALUE; break; case RCC_CFGR_SWS_HSE: /* HSE used as system clock source */ common_system_clock = HSE_VALUE; break; case RCC_CFGR_SWS_PLL1: /* PLL1 used as system clock source */ /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN SYSCLK = PLL_VCO / PLLR */ pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC); pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1)>> 4) ; pllfracen = ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN)>>RCC_PLLCFGR_PLL1FRACEN_Pos); fracn1 = (float_t)(uint32_t)(pllfracen* ((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN1)>> 3)); if (pllm != 0U) { switch (pllsource) { case RCC_PLLCKSELR_PLLSRC_HSI: /* HSI used as PLL clock source */ hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)) ; pllvco = ( (float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 ); break; case RCC_PLLCKSELR_PLLSRC_CSI: /* CSI used as PLL clock source */ pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 ); break; case RCC_PLLCKSELR_PLLSRC_HSE: /* HSE used as PLL clock source */ pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 ); break; default: hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)) ; pllvco = ((float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 ); break; } pllp = (((RCC->PLL1DIVR & RCC_PLL1DIVR_P1) >>9) + 1U ) ; common_system_clock = (uint32_t)(float_t)(pllvco/(float_t)pllp); } else { common_system_clock = 0U; } break; default: common_system_clock = (uint32_t) (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)); break; } /* Compute SystemClock frequency --------------------------------------------------*/ #if defined (RCC_D1CFGR_D1CPRE) tmp = D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_D1CPRE)>> RCC_D1CFGR_D1CPRE_Pos]; /* common_system_clock frequency : CM7 CPU frequency */ common_system_clock >>= tmp; /* SystemD2Clock frequency : CM4 CPU, AXI and AHBs Clock frequency */ SystemD2Clock = (common_system_clock >> ((D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_HPRE)>> RCC_D1CFGR_HPRE_Pos]) & 0x1FU)); #else tmp = D1CorePrescTable[(RCC->CDCFGR1 & RCC_CDCFGR1_CDCPRE)>> RCC_CDCFGR1_CDCPRE_Pos]; /* common_system_clock frequency : CM7 CPU frequency */ common_system_clock >>= tmp; /* SystemD2Clock frequency : AXI and AHBs Clock frequency */ SystemD2Clock = (common_system_clock >> ((D1CorePrescTable[(RCC->CDCFGR1 & RCC_CDCFGR1_HPRE)>> RCC_CDCFGR1_HPRE_Pos]) & 0x1FU)); #endif #if defined(DUAL_CORE) && defined(CORE_CM4) SystemCoreClock = SystemD2Clock; #else SystemCoreClock = common_system_clock; #endif /* DUAL_CORE && CORE_CM4 */ } /** * @} */ /** * @} */ /** * @} */ ================================================ FILE: 3rd_party/nucleo-h743zi/system_stm32h7xx.h ================================================ /** ****************************************************************************** * @file system_stm32h7xx.h * @author MCD Application Team * @brief CMSIS Cortex-Mx Device System Source File for STM32H7xx devices. ****************************************************************************** * @attention * * Copyright (c) 2017 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /** @addtogroup CMSIS * @{ */ /** @addtogroup stm32h7xx_system * @{ */ /** * @brief Define to prevent recursive inclusion */ #ifndef SYSTEM_STM32H7XX_H #define SYSTEM_STM32H7XX_H #ifdef __cplusplus extern "C" { #endif /** @addtogroup STM32H7xx_System_Includes * @{ */ /** * @} */ /** @addtogroup STM32H7xx_System_Exported_types * @{ */ /* This variable is updated in three ways: 1) by calling CMSIS function SystemCoreClockUpdate() 2) by calling HAL API function HAL_RCC_GetSysClockFreq() 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency Note: If you use this function to configure the system clock; then there is no need to call the 2 first functions listed above, since SystemCoreClock variable is updated automatically. */ extern uint32_t SystemCoreClock; /*!< System Domain1 Clock Frequency */ extern uint32_t SystemD2Clock; /*!< System Domain2 Clock Frequency */ extern const uint8_t D1CorePrescTable[16] ; /*!< D1CorePrescTable prescalers table values */ /** * @} */ /** @addtogroup STM32H7xx_System_Exported_Constants * @{ */ /** * @} */ /** @addtogroup STM32H7xx_System_Exported_Macros * @{ */ /** * @} */ /** @addtogroup STM32H7xx_System_Exported_Functions * @{ */ extern void SystemInit(void); extern void SystemCoreClockUpdate(void); /** * @} */ #ifdef __cplusplus } #endif #endif /* SYSTEM_STM32H7XX_H */ /** * @} */ /** * @} */ ================================================ FILE: 3rd_party/nucleo-l053r8/README.txt ================================================ This folder contains the support code for the NUCLEO-L053R8 board. CMSIS-Compliant Device Files ============================ The code also includes the CMSIS-compliant interface to the STM32L053xx MCU files: stm32l0xx.h stm32l053xx.h system_stm32l0xx.h system_stm32l0xx.c arm\startup_stm32l053xx.s gnu\startup_stm32l053xx.c iar\startup_stm32l053xx.s Adjusting the CPU Clock Speed ============================= The current setting is to run at 2MHz from the MSI (internal oscillator), but the CPU clock speed can be modified by editing the file system_stm32l0xx.c. Ther file system_stm32l0xx.c.pll provides an example of clock setting using the PLL driven from the MSE. *** NOTE: The NUCLEO boards have a wide range of possible clock selections, depending on the solder bridge configuration. Please see Chapter 5.7 "OSC clock" in the STM32 NUCLEO Boards User Manual (ST document UM1724) for more information. *** ================================================ FILE: 3rd_party/nucleo-l053r8/arm/startup_stm32l053xx.s ================================================ ;/***************************************************************************/ ; * @file startup_stm32l053xx.s for ARM-KEIL ARM assembler ; * @brief CMSIS Cortex-M0+ Core Device Startup File for STM32L053xx ; * @version CMSIS 5.9.0 ; * @date 1 Feb 2023 ; * ; * Modified by Quantum Leaps: ; * - Added relocating of the Vector Table to free up the 256B region at 0x0 ; * for NULL-pointer protection by the MPU. ; * - Modified all exception handlers to branch to assert_failed() ; * instead of locking up the CPU inside an endless loop. ; * ; * @description ; * Created from the CMSIS template for the specified device ; * Quantum Leaps, www.state-machine.com ; * ; * @note ; * The symbols Stack_Size and Heap_Size should be provided on the command- ; * line options to the assembler, for example as: ; * --pd "Stack_Size SETA 1024" --pd "Heap_Size SETA 0" ;****************************************************************************** ; Allocate space for the stack. ; AREA STACK, NOINIT, READWRITE, ALIGN=3 __stack_base StackMem SPACE Stack_Size ; provided in command-line option, for example: ; --pd "Stack_Size SETA 512" __stack_limit __initial_sp ;****************************************************************************** ; Allocate space for the heap. ; AREA HEAP, NOINIT, READWRITE, ALIGN=3 __heap_base HeapMem SPACE Heap_Size ; provided in command-line option, for example: ; --pd "Heap_Size SETA 0" __heap_limit ; Indicate that the code in this file preserves 8-byte alignment of the stack. PRESERVE8 ;****************************************************************************** ; The vector table. ; ; Place code into the reset code section. AREA RESET, DATA, READONLY, ALIGN=8 EXPORT __Vectors EXPORT __Vectors_End EXPORT __Vectors_Size __Vectors ; Initial Vector Table before relocation DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD SVC_Handler ; SVCall handler DCD DebugMon_Handler ; Debug Monitor handler DCD Default_Handler ; Reserved DCD PendSV_Handler ; PendSV handler DCD SysTick_Handler ; SysTick handler ; IRQ handlers... DCD WWDG_IRQHandler ; [ 0] Window Watchdog DCD PVD_IRQHandler ; [ 1] PVD through EXTI Line detect DCD RTC_IRQHandler ; [ 2] RTC through EXTI Line DCD FLASH_IRQHandler ; [ 3] FLASH DCD RCC_CRS_IRQHandler ; [ 4] RCC and CRS DCD EXTI0_1_IRQHandler ; [ 5] EXTI Line 0 and 1 DCD EXTI2_3_IRQHandler ; [ 6] EXTI Line 2 and 3 DCD EXTI4_15_IRQHandler ; [ 7] EXTI Line 4 to 15 DCD TSC_IRQHandler ; [ 8] TSC DCD DMA1_Channel1_IRQHandler ; [ 9] DMA1 Channel 1 DCD DMA1_Channel2_3_IRQHandler ; [10] DMA1 Channel 2 and Channel 3 DCD DMA1_Channel4_5_6_7_IRQHandler ; [11] DMA1 Channel 4, 5, 6 and 7 DCD ADC1_COMP_IRQHandler ; [12] ADC1, COMP1 and COMP2 DCD LPTIM1_IRQHandler ; [13] LPTIM1 DCD Reserved14_IRQHandler ; [14] Reserved DCD TIM2_IRQHandler ; [15] TIM2 DCD Reserved16_IRQHandler ; [16] Reserved DCD TIM6_DAC_IRQHandler ; [17] TIM6 and DAC DCD Reserved18_IRQHandler ; [18] Reserved DCD Reserved19_IRQHandler ; [19] Reserved DCD TIM21_IRQHandler ; [20] TIM21 DCD Reserved21_IRQHandler ; [21] Reserved DCD TIM22_IRQHandler ; [22] TIM22 DCD I2C1_IRQHandler ; [23] I2C1 DCD I2C2_IRQHandler ; [24] I2C2 DCD SPI1_IRQHandler ; [25] SPI1 DCD SPI2_IRQHandler ; [26] SPI2 DCD USART1_IRQHandler ; [27] USART1 DCD USART2_IRQHandler ; [28] USART2 DCD RNG_LPUART1_IRQHandler ; [29] RNG and LPUART1 DCD LCD_IRQHandler ; [30] LCD DCD USB_IRQHandler ; [31] USB __Vectors_End __Vectors_Size EQU __Vectors_End - __Vectors ;****************************************************************************** ; This is the code for exception handlers. ; AREA |.text|, CODE, READONLY ;****************************************************************************** ; This is the code that gets called when the processor first starts execution ; following a reset event. ; Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main IMPORT assert_failed LDR r0,=SystemInit ; CMSIS system initialization BLX r0 ; Call the C library enty point that handles startup. This will copy ; the .data section initializers from flash to SRAM and zero fill the ; .bss section. ; NOTE: The __main function clears the C stack as well LDR r0,=__main BX r0 ; __main calls the main() function, which should not return, ; but just in case jump to assert_failed() if main returns. LDR r0,=str_EXIT MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_EXIT DCB "EXIT" ALIGN ENDP ;****************************************************************************** NMI_Handler PROC EXPORT NMI_Handler [WEAK] IMPORT assert_failed LDR r0,=str_NMI MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_NMI DCB "NMI" ALIGN ENDP ;****************************************************************************** HardFault_Handler PROC EXPORT HardFault_Handler [WEAK] IMPORT assert_failed LDR r0,=str_HardFault MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_HardFault DCB "HardFault" ALIGN ENDP ;****************************************************************************** ; ; Weak non-fault handlers... ; ;****************************************************************************** SVC_Handler PROC EXPORT SVC_Handler [WEAK] IMPORT assert_failed LDR r0,=str_SVC MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_SVC DCB "SVC" ALIGN ENDP ;****************************************************************************** DebugMon_Handler PROC EXPORT DebugMon_Handler [WEAK] IMPORT assert_failed LDR r0,=str_DebugMon MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_DebugMon DCB "DebugMon" ALIGN ENDP ;****************************************************************************** PendSV_Handler PROC EXPORT PendSV_Handler [WEAK] IMPORT assert_failed LDR r0,=str_PendSV MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_PendSV DCB "PendSV" ALIGN ENDP ;****************************************************************************** SysTick_Handler PROC EXPORT SysTick_Handler [WEAK] IMPORT assert_failed LDR r0,=str_SysTick MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_SysTick DCB "SysTick" ALIGN ENDP ;****************************************************************************** Default_Handler PROC EXPORT WWDG_IRQHandler [WEAK] EXPORT PVD_IRQHandler [WEAK] EXPORT RTC_IRQHandler [WEAK] EXPORT FLASH_IRQHandler [WEAK] EXPORT RCC_CRS_IRQHandler [WEAK] EXPORT EXTI0_1_IRQHandler [WEAK] EXPORT EXTI2_3_IRQHandler [WEAK] EXPORT EXTI4_15_IRQHandler [WEAK] EXPORT TSC_IRQHandler [WEAK] EXPORT DMA1_Channel1_IRQHandler [WEAK] EXPORT DMA1_Channel2_3_IRQHandler [WEAK] EXPORT DMA1_Channel4_5_6_7_IRQHandler [WEAK] EXPORT ADC1_COMP_IRQHandler [WEAK] EXPORT LPTIM1_IRQHandler [WEAK] EXPORT TIM2_IRQHandler [WEAK] EXPORT TIM6_DAC_IRQHandler [WEAK] EXPORT TIM21_IRQHandler [WEAK] EXPORT TIM22_IRQHandler [WEAK] EXPORT I2C1_IRQHandler [WEAK] EXPORT I2C2_IRQHandler [WEAK] EXPORT SPI1_IRQHandler [WEAK] EXPORT SPI2_IRQHandler [WEAK] EXPORT USART1_IRQHandler [WEAK] EXPORT USART2_IRQHandler [WEAK] EXPORT RNG_LPUART1_IRQHandler [WEAK] EXPORT LCD_IRQHandler [WEAK] EXPORT USB_IRQHandler [WEAK] EXPORT Reserved14_IRQHandler [WEAK] EXPORT Reserved16_IRQHandler [WEAK] EXPORT Reserved18_IRQHandler [WEAK] EXPORT Reserved19_IRQHandler [WEAK] EXPORT Reserved21_IRQHandler [WEAK] WWDG_IRQHandler PVD_IRQHandler RTC_IRQHandler FLASH_IRQHandler RCC_CRS_IRQHandler EXTI0_1_IRQHandler EXTI2_3_IRQHandler EXTI4_15_IRQHandler TSC_IRQHandler DMA1_Channel1_IRQHandler DMA1_Channel2_3_IRQHandler DMA1_Channel4_5_6_7_IRQHandler ADC1_COMP_IRQHandler LPTIM1_IRQHandler TIM2_IRQHandler TIM6_DAC_IRQHandler TIM21_IRQHandler TIM22_IRQHandler I2C1_IRQHandler I2C2_IRQHandler SPI1_IRQHandler SPI2_IRQHandler USART1_IRQHandler USART2_IRQHandler RNG_LPUART1_IRQHandler LCD_IRQHandler USB_IRQHandler Reserved14_IRQHandler Reserved16_IRQHandler Reserved18_IRQHandler Reserved19_IRQHandler Reserved21_IRQHandler LDR r0,=str_Undefined MOVS r1,#1 LDR r2,=__initial_sp ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_Undefined DCB "Undefined" ALIGN ENDP ALIGN ; make sure the end of this section is aligned ;****************************************************************************** ; The function expected of the C library startup code for defining the stack ; and heap memory locations. For the C library version of the startup code, ; provide this function so that the C library initialization code can find out ; the location of the stack and heap. ; IF :DEF: __MICROLIB EXPORT __initial_sp EXPORT __stack_limit EXPORT __heap_base EXPORT __heap_limit ELSE IMPORT __use_two_region_memory EXPORT __user_initial_stackheap __user_initial_stackheap PROC LDR R0, =__heap_base LDR R1, =__stack_limit LDR R2, =__heap_limit LDR R3, =__stack_base BX LR ENDP ENDIF ALIGN ; make sure the end of this section is aligned END ; end of module ================================================ FILE: 3rd_party/nucleo-l053r8/gnu/nucleo-l053r8.ld ================================================ /***************************************************************************** * Linker script for for STM32L053R8, GNU-ARM linker * * Q u a n t u m L e a P s * ------------------------ * Modern Embedded Software * * Copyright (C) 2005 Quantum Leaps, LLC . * * SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial * * This software is dual-licensed under the terms of the open source GNU * General Public License version 3 (or any later version), or alternatively, * under the terms of one of the closed source Quantum Leaps commercial * licenses. * * The terms of the open source GNU General Public License version 3 * can be found at: * * The terms of the closed source Quantum Leaps commercial licenses * can be found at: * * Redistributions in source code must retain this top-level comment block. * Plagiarizing this software to sidestep the license obligations is illegal. * * Contact information: * * *****************************************************************************/ OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(Reset_Handler) /* entry Point */ MEMORY { /* memory map of STM32L053R8 */ ROM (rx) : ORIGIN = 0x08000000, LENGTH = 64K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K } /* The size of the stack used by the application. NOTE: you need to adjust */ STACK_SIZE = 2048; /* The size of the heap used by the application. NOTE: you need to adjust */ HEAP_SIZE = 0; SECTIONS { .isr_vector : { /* the vector table goes FIRST into ROM */ KEEP(*(.isr_vector)) /* vector table */ . = ALIGN(4); } >ROM .text : { /* code and constants */ . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); } >ROM .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >ROM .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >ROM .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(.fini_array*)) KEEP (*(SORT(.fini_array.*))) PROVIDE_HIDDEN (__fini_array_end = .); } >ROM _etext = .; /* global symbols at end of code */ .stack : { __stack_start__ = .; . = . + STACK_SIZE; . = ALIGN(4); __stack_end__ = .; } >RAM .data : AT (_etext) { __data_load = LOADADDR (.data); __data_start = .; *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); __data_end__ = .; _edata = __data_end__; } >RAM .bss : { __bss_start__ = .; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = .; } >RAM __exidx_start = .; .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM __exidx_end = .; PROVIDE ( end = _ebss ); PROVIDE ( _end = _ebss ); PROVIDE ( __end__ = _ebss ); .heap : { __heap_start__ = .; . = . + HEAP_SIZE; . = ALIGN(4); __heap_end__ = .; } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } } ================================================ FILE: 3rd_party/nucleo-l053r8/gnu/startup_stm32l053xx.c ================================================ /* File: startup_stm32l053xx.c for GNU-ARM * Purpose: startup file for STM32L053xx Cortex-M0+ device. * Should be used with GCC 'GNU Tools ARM Embedded' * Version: CMSIS 5.0.1 * Date: 2017-09-13 * * Modified by Quantum Leaps: * - Added relocating of the Vector Table to free up the 256B region at 0x0 * for NULL-pointer protection by the MPU. * - Modified all exception handlers to branch to assert_failed() * instead of locking up the CPU inside an endless loop. * * Created from the CMSIS template for the specified device * Quantum Leaps, www.state-machine.com * * NOTE: * The function assert_failed defined at the end of this file defines * the error/assertion handling policy for the application and might * need to be customized for each project. This function is defined in * assembly to re-set the stack pointer, in case it is corrupted by the * time assert_failed is called. */ /* start and end of stack defined in the linker script ---------------------*/ /*extern int __stack_start__;*/ extern int __stack_end__; /* Weak prototypes for error handlers --------------------------------------*/ /** * \note * The function assert_failed defined at the end of this file defines * the error/assertion handling policy for the application and might * need to be customized for each project. This function is defined in * assembly to avoid accessing the stack, which might be corrupted by * the time assert_failed is called. */ __attribute__ ((naked, noreturn)) void assert_failed(char const *module, int loc); /* Function prototypes -----------------------------------------------------*/ void Default_Handler(void); /* Default empty handler */ void Reset_Handler(void); /* Reset Handler */ void SystemInit(void); /* CMSIS system initialization */ /*---------------------------------------------------------------------------- * weak aliases for each Exception handler to the Default_Handler. * Any function with the same name will override these definitions. */ /* Cortex-M Processor fault exceptions... */ void NMI_Handler (void) __attribute__ ((weak)); void HardFault_Handler (void) __attribute__ ((weak)); void MemManage_Handler (void) __attribute__ ((weak)); void BusFault_Handler (void) __attribute__ ((weak)); void UsageFault_Handler (void) __attribute__ ((weak)); /* Cortex-M Processor non-fault exceptions... */ void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); void DebugMon_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); /* external interrupts... */ void WWDG_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void PVD_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void RTC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void FLASH_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void RCC_CRS_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void EXTI0_1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void EXTI2_3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void EXTI4_15_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void TSC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void DMA1_Channel1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void DMA1_Channel2_3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void DMA1_Channel4_5_6_7_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void ADC1_COMP_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void LPTIM1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void TIM2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void TIM6_DAC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void TIM21_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void TIM22_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void I2C1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void I2C2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void SPI1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void SPI2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void USART1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void USART2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void RNG_LPUART1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); void LCD_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void USB_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved14_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved16_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved18_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved19_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void Reserved21_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); /*..........................................................................*/ __attribute__ ((section(".isr_vector"))) int const g_pfnVectors[] = { (int)&__stack_end__, /* Top of Stack */ (int)&Reset_Handler, /* Reset Handler */ (int)&NMI_Handler, /* NMI Handler */ (int)&HardFault_Handler, /* Hard Fault Handler */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&Default_Handler, /* Reserved */ (int)&SVC_Handler, /* SVCall handler */ (int)&DebugMon_Handler, /* Debug monitor handler */ (int)&Default_Handler, /* Reserved */ (int)&PendSV_Handler, /* The PendSV handler */ (int)&SysTick_Handler, /* The SysTick handler */ /*IRQ handlers... */ (int)&WWDG_IRQHandler, /* [ 0] Window Watchdog */ (int)&PVD_IRQHandler, /* [ 1] PVD through EXTI Line detect */ (int)&RTC_IRQHandler, /* [ 2] RTC through EXTI Line */ (int)&FLASH_IRQHandler, /* [ 3] FLASH */ (int)&RCC_CRS_IRQHandler, /* [ 4] RCC and CRS */ (int)&EXTI0_1_IRQHandler, /* [ 5] EXTI Line 0 and 1 */ (int)&EXTI2_3_IRQHandler, /* [ 6] EXTI Line 2 and 3 */ (int)&EXTI4_15_IRQHandler, /* [ 7] EXTI Line 4 to 15 */ (int)&TSC_IRQHandler, /* [ 8] TSC */ (int)&DMA1_Channel1_IRQHandler, /* [ 9] DMA1 Channel 1 */ (int)&DMA1_Channel2_3_IRQHandler,/* [10] DMA1 Channel 2 and Channel 3 */ (int)&DMA1_Channel4_5_6_7_IRQHandler, /* [11] DMA1 Channel 4, 5, 6 and 7 */ (int)&ADC1_COMP_IRQHandler, /* [12] ADC1, COMP1 and COMP2 */ (int)&LPTIM1_IRQHandler, /* [13] LPTIM1 */ (int)&Reserved14_IRQHandler, /* [14] Reserved */ (int)&TIM2_IRQHandler, /* [15] TIM2 */ (int)&Reserved16_IRQHandler, /* [16] Reserved */ (int)&TIM6_DAC_IRQHandler, /* [17] TIM6 and DAC */ (int)&Reserved18_IRQHandler, /* [18] Reserved */ (int)&Reserved19_IRQHandler, /* [19] Reserved */ (int)&TIM21_IRQHandler, /* [20] TIM21 */ (int)&Reserved21_IRQHandler, /* [21] Reserved */ (int)&TIM22_IRQHandler, /* [22] TIM22 */ (int)&I2C1_IRQHandler, /* [23] I2C1 */ (int)&I2C2_IRQHandler, /* [24] I2C2 */ (int)&SPI1_IRQHandler, /* [25] SPI1 */ (int)&SPI2_IRQHandler, /* [26] SPI2 */ (int)&USART1_IRQHandler, /* [27] USART1 */ (int)&USART2_IRQHandler, /* [28] USART2 */ (int)&RNG_LPUART1_IRQHandler, /* [29] RNG and LPUART1 */ (int)&LCD_IRQHandler, /* [30] LCD */ (int)&USB_IRQHandler, /* [31] USB */ }; /* reset handler -----------------------------------------------------------*/ __attribute__((naked)) void Reset_Handler(void); void Reset_Handler(void) { extern int main(void); extern int __libc_init_array(void); extern unsigned __data_start; /* start of .data in the linker script */ extern unsigned __data_end__; /* end of .data in the linker script */ extern unsigned const __data_load; /* initialization values for .data */ extern unsigned __bss_start__; /* start of .bss in the linker script */ extern unsigned __bss_end__; /* end of .bss in the linker script */ extern void software_init_hook(void) __attribute__((weak)); SystemInit(); /* CMSIS system initialization */ /* copy the data segment initializers from flash to RAM... */ unsigned const *src = &__data_load; unsigned *dst; for (dst = &__data_start; dst < &__data_end__; ++dst, ++src) { *dst = *src; } /* zero fill the .bss segment in RAM... */ for (dst = &__bss_start__; dst < &__bss_end__; ++dst) { *dst = 0; } /* init hook provided? */ if (&software_init_hook != (void (*)(void))(0)) { /* give control to the RTOS */ software_init_hook(); /* this will also call __libc_init_array */ } else { /* call all static constructors in C++ (harmless in C programs) */ __libc_init_array(); (void)main(); /* application's entry point; should never return! */ } /* the previous code should not return, but assert just in case... */ assert_failed("Reset_Handler", 1U); } /* fault exception handlers ------------------------------------------------*/ __attribute__((naked)) void NMI_Handler(void); void NMI_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("NMI_Handler", 1U); } /*..........................................................................*/ __attribute__((naked)) void HardFault_Handler(void); void HardFault_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("HardFault_Handler", 1U); } /*..........................................................................*/ __attribute__((naked)) void Default_Handler(void); void Default_Handler(void) { /* reset the SP to the initial value in case of stack overflow */ __asm volatile (" MOV sp,%0" : : "r" (&__stack_end__)); assert_failed("Default_Handler", 1U); } ================================================ FILE: 3rd_party/nucleo-l053r8/iar/startup_stm32l053xx.s ================================================ ;/***************************************************************************/ ; * @file startup_startup_stm32l053xx.s for IAR ARM assembler ; * @brief CMSIS Cortex-M0+ Core Device Startup File for STM32L053xx ; * @version CMSIS 5.9.0 ; * @date 1 Feb 2023 ; * ; * Modified by Quantum Leaps: ; * - Added relocating of the Vector Table to free up the 256B region at 0x0 ; * for NULL-pointer protection by the MPU. ; * - Modified all exception handlers to branch to assert_failed() ; * instead of locking up the CPU inside an endless loop. ; * ; * @description ; * Created from the CMSIS template for the specified device ; * Quantum Leaps, www.state-machine.com ; * MODULE ?cstartup ; Forward declaration of sections. SECTION CSTACK:DATA:NOROOT(3) SECTION .intvec:CODE:NOROOT(8) PUBLIC __vector_table PUBLIC __Vectors PUBLIC __Vectors_End PUBLIC __Vectors_Size ;****************************************************************************** ; The vector table. ; DATA __vector_table ; Initial Vector Table before relocation DCD sfe(CSTACK) DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD Default_Handler ; Reserved DCD SVC_Handler ; SVCall handler DCD DebugMon_Handler ; Debug Monitor handler DCD Default_Handler ; Reserved DCD PendSV_Handler ; PendSV handler DCD SysTick_Handler ; SysTick handler ; IRQ handlers... DCD WWDG_IRQHandler ; [ 0] Window Watchdog DCD PVD_IRQHandler ; [ 1] PVD through EXTI Line detect DCD RTC_IRQHandler ; [ 2] RTC through EXTI Line DCD FLASH_IRQHandler ; [ 3] FLASH DCD RCC_CRS_IRQHandler ; [ 4] RCC and CRS DCD EXTI0_1_IRQHandler ; [ 5] EXTI Line 0 and 1 DCD EXTI2_3_IRQHandler ; [ 6] EXTI Line 2 and 3 DCD EXTI4_15_IRQHandler ; [ 7] EXTI Line 4 to 15 DCD TSC_IRQHandler ; [ 8] TSC DCD DMA1_Channel1_IRQHandler ; [ 9] DMA1 Channel 1 DCD DMA1_Channel2_3_IRQHandler ; [10] DMA1 Channel 2 and Channel 3 DCD DMA1_Channel4_5_6_7_IRQHandler ; [11] DMA1 Channel 4, 5, 6 and 7 DCD ADC1_COMP_IRQHandler ; [12] ADC1, COMP1 and COMP2 DCD LPTIM1_IRQHandler ; [13] LPTIM1 DCD Reserved14_IRQHandler ; [14] Reserved DCD TIM2_IRQHandler ; [15] TIM2 DCD Reserved16_IRQHandler ; [16] Reserved DCD TIM6_DAC_IRQHandler ; [17] TIM6 and DAC DCD Reserved18_IRQHandler ; [18] Reserved DCD Reserved19_IRQHandler ; [19] Reserved DCD TIM21_IRQHandler ; [20] TIM21 DCD Reserved21_IRQHandler ; [21] Reserved DCD TIM22_IRQHandler ; [22] TIM22 DCD I2C1_IRQHandler ; [23] I2C1 DCD I2C2_IRQHandler ; [24] I2C2 DCD SPI1_IRQHandler ; [25] SPI1 DCD SPI2_IRQHandler ; [26] SPI2 DCD USART1_IRQHandler ; [27] USART1 DCD USART2_IRQHandler ; [28] USART2 DCD RNG_LPUART1_IRQHandler ; [29] RNG and LPUART1 DCD LCD_IRQHandler ; [30] LCD DCD USB_IRQHandler ; [31] USB __Vectors_End __Vectors EQU __vector_table __Vectors_Size EQU __Vectors_End - __Vectors ;****************************************************************************** ; This is the code for exception handlers. ; SECTION .text:CODE:REORDER:NOROOT(2) ;****************************************************************************** ; This is the code that gets called when theessor first starts execution ; following a reset event. ; PUBWEAK Reset_Handler EXTERN SystemInit EXTERN __iar_program_start EXTERN assert_failed Reset_Handler LDR r0,=SystemInit ; CMSIS system initialization BLX r0 ; pre-fill the CSTACK with 0xDEADBEEF................... LDR r0,=0xDEADBEEF MOV r1,r0 LDR r2,=sfb(CSTACK) LDR r3,=sfe(CSTACK) Reset_stackInit_fill: STMIA r2!,{r0,r1} CMP r2,r3 BLT.N Reset_stackInit_fill LDR r0,=__iar_program_start ; IAR startup code BLX r0 ; __iar_program_start calls the main() function, which should not return, ; but just in case jump to assert_failed() if main returns. LDR r0,=str_EXIT MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_EXIT DCB "EXIT" ALIGNROM 2 ;****************************************************************************** PUBWEAK NMI_Handler NMI_Handler LDR r0,=str_NMI MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_NMI DCB "NMI" ALIGNROM 2 ;****************************************************************************** PUBWEAK HardFault_Handler HardFault_Handler LDR r0,=str_HardFault MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_HardFault DCB "HardFault" ALIGNROM 2 ;****************************************************************************** ; ; Weak non-fault handlers... ; ;****************************************************************************** PUBWEAK SVC_Handler SVC_Handler LDR r0,=str_SVC MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_SVC DCB "SVC" ALIGNROM 2 ;****************************************************************************** PUBWEAK DebugMon_Handler DebugMon_Handler LDR r0,=str_DebugMon MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_DebugMon DCB "DebugMon" ALIGNROM 2 ;****************************************************************************** PUBWEAK PendSV_Handler PendSV_Handler LDR r0,=str_PendSV MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_PendSV DCB "PendSV" ALIGNROM 2 ;****************************************************************************** PUBWEAK SysTick_Handler SysTick_Handler LDR r0,=str_SysTick MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_SysTick DCB "SysTick" ALIGNROM 2 ;****************************************************************************** ; Weak IRQ handlers... ; PUBWEAK Default_Handler PUBWEAK WWDG_IRQHandler PUBWEAK PVD_IRQHandler PUBWEAK RTC_IRQHandler PUBWEAK FLASH_IRQHandler PUBWEAK RCC_CRS_IRQHandler PUBWEAK EXTI0_1_IRQHandler PUBWEAK EXTI2_3_IRQHandler PUBWEAK EXTI4_15_IRQHandler PUBWEAK TSC_IRQHandler PUBWEAK DMA1_Channel1_IRQHandler PUBWEAK DMA1_Channel2_3_IRQHandler PUBWEAK DMA1_Channel4_5_6_7_IRQHandler PUBWEAK ADC1_COMP_IRQHandler PUBWEAK LPTIM1_IRQHandler PUBWEAK TIM2_IRQHandler PUBWEAK TIM6_DAC_IRQHandler PUBWEAK TIM21_IRQHandler PUBWEAK TIM22_IRQHandler PUBWEAK I2C1_IRQHandler PUBWEAK I2C2_IRQHandler PUBWEAK SPI1_IRQHandler PUBWEAK SPI2_IRQHandler PUBWEAK USART1_IRQHandler PUBWEAK USART2_IRQHandler PUBWEAK RNG_LPUART1_IRQHandler PUBWEAK LCD_IRQHandler PUBWEAK USB_IRQHandler PUBWEAK Reserved14_IRQHandler PUBWEAK Reserved16_IRQHandler PUBWEAK Reserved18_IRQHandler PUBWEAK Reserved19_IRQHandler PUBWEAK Reserved21_IRQHandler Default_Handler WWDG_IRQHandler PVD_IRQHandler RTC_IRQHandler FLASH_IRQHandler RCC_CRS_IRQHandler EXTI0_1_IRQHandler EXTI2_3_IRQHandler EXTI4_15_IRQHandler TSC_IRQHandler DMA1_Channel1_IRQHandler DMA1_Channel2_3_IRQHandler DMA1_Channel4_5_6_7_IRQHandler ADC1_COMP_IRQHandler LPTIM1_IRQHandler TIM2_IRQHandler TIM6_DAC_IRQHandler TIM21_IRQHandler TIM22_IRQHandler I2C1_IRQHandler I2C2_IRQHandler SPI1_IRQHandler SPI2_IRQHandler USART1_IRQHandler USART2_IRQHandler RNG_LPUART1_IRQHandler LCD_IRQHandler USB_IRQHandler Reserved14_IRQHandler Reserved16_IRQHandler Reserved18_IRQHandler Reserved19_IRQHandler Reserved21_IRQHandler LDR r0,=str_Undefined MOVS r1,#1 LDR r2,=sfe(CSTACK) ; re-set the SP in case of stack overflow MOV sp,r2 LDR r2,=assert_failed BX r2 str_Undefined DCB "Undefined" ALIGNROM 2 END ; end of module ================================================ FILE: 3rd_party/nucleo-l053r8/stm32l053xx.h ================================================ /** ****************************************************************************** * @file stm32l053xx.h * @author MCD Application Team * @version V1.0.0RC1 * @date 15-April-2014 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer Header File. * This file contains all the peripheral register's definitions, bits * definitions and memory mapping for STM32L0xx devices. * * This file contains: * - Data structures and the address mapping for all peripherals * - Peripheral's registers declarations and bits definition * - Macros to access peripheral’s registers hardware * ****************************************************************************** * @attention * *

© COPYRIGHT(c) 2014 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /** @addtogroup CMSIS * @{ */ /** @addtogroup stm32l053xx * @{ */ #ifndef __STM32L053xx_H #define __STM32L053xx_H #ifdef __cplusplus extern "C" { #endif /** @addtogroup Configuration_section_for_CMSIS * @{ */ /** * @brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ #define __CM0PLUS_REV 0 /*!< Core Revision r0p0 */ #define __MPU_PRESENT 1 /*!< STM32L0xx provides an MPU */ #define __VTOR_PRESENT 1 /*!< Vector Table Register supported */ #define __NVIC_PRIO_BITS 2 /*!< STM32L0xx uses 2 Bits for the Priority Levels */ #define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ /** * @} */ /** @addtogroup Peripheral_interrupt_number_definition * @{ */ /** * @brief STM32L0xx Interrupt Number Definition, according to the selected device * in @ref Library_configuration_section */ /*!< Interrupt Number Definition */ typedef enum { /****** Cortex-M0 Processor Exceptions Numbers ******************************************************/ NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ HardFault_IRQn = -13, /*!< 3 Cortex-M0+ Hard Fault Interrupt */ SVC_IRQn = -5, /*!< 11 Cortex-M0+ SV Call Interrupt */ PendSV_IRQn = -2, /*!< 14 Cortex-M0+ Pend SV Interrupt */ SysTick_IRQn = -1, /*!< 15 Cortex-M0+ System Tick Interrupt */ /****** STM32L-0 specific Interrupt Numbers *********************************************************/ WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ PVD_IRQn = 1, /*!< PVD through EXTI Line detect Interrupt */ RTC_IRQn = 2, /*!< RTC through EXTI Line Interrupt */ FLASH_IRQn = 3, /*!< FLASH Interrupt */ RCC_CRS_IRQn = 4, /*!< RCC and CRS Interrupts */ EXTI0_1_IRQn = 5, /*!< EXTI Line 0 and 1 Interrupts */ EXTI2_3_IRQn = 6, /*!< EXTI Line 2 and 3 Interrupts */ EXTI4_15_IRQn = 7, /*!< EXTI Line 4 to 15 Interrupts */ TSC_IRQn = 8, /*!< TSC Interrupt */ DMA1_Channel1_IRQn = 9, /*!< DMA1 Channel 1 Interrupt */ DMA1_Channel2_3_IRQn = 10, /*!< DMA1 Channel 2 and Channel 3 Interrupts */ DMA1_Channel4_5_6_7_IRQn = 11, /*!< DMA1 Channel 4, Channel 5, Channel 6 and Channel 7 Interrupts */ ADC1_COMP_IRQn = 12, /*!< ADC1, COMP1 and COMP2 Interrupts */ LPTIM1_IRQn = 13, /*!< LPTIM1 Interrupt */ TIM2_IRQn = 15, /*!< TIM2 Interrupt */ TIM6_DAC_IRQn = 17, /*!< TIM6 and DAC Interrupts */ TIM21_IRQn = 20, /*!< TIM21 Interrupt */ TIM22_IRQn = 22, /*!< TIM22 Interrupt */ I2C1_IRQn = 23, /*!< I2C1 Interrupt */ I2C2_IRQn = 24, /*!< I2C2 Interrupt */ SPI1_IRQn = 25, /*!< SPI1 Interrupt */ SPI2_IRQn = 26, /*!< SPI2 Interrupt */ USART1_IRQn = 27, /*!< USART1 Interrupt */ USART2_IRQn = 28, /*!< USART2 Interrupt */ RNG_LPUART1_IRQn = 29, /*!< RNG and LPUART1 Interrupts */ LCD_IRQn = 30, /*!< LCD Interrupts */ USB_IRQn = 31 /*!< USB global Interrupt */ } IRQn_Type; /*! Exception prototypes */ void SVC_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); /*! IRQ prototypes */ void WWDG_IRQHandler(void); void PVD_IRQHandler(void); void RTC_IRQHandler(void); void FLASH_IRQHandler(void); void RCC_CRS_IRQHandler(void); void EXTI0_1_IRQHandler(void); void EXTI2_3_IRQHandler(void); void EXTI4_15_IRQHandler(void); void TSC_IRQHandler(void); void DMA1_Channel1_IRQHandler(void); void DMA1_Channel2_3_IRQHandler(void); void DMA1_Channel4_5_6_7_IRQHandler(void); void ADC1_COMP_IRQHandler(void); void LPTIM1_IRQHandler(void); void TIM2_IRQHandler(void); void TIM6_DAC_IRQHandler(void); void TIM21_IRQHandler(void); void TIM22_IRQHandler(void); void I2C1_IRQHandler(void); void I2C2_IRQHandler(void); void SPI1_IRQHandler(void); void SPI2_IRQHandler(void); void USART1_IRQHandler(void); void USART2_IRQHandler(void); void RNG_LPUART1_IRQHandler(void); void LCD_IRQHandler(void); void USB_IRQHandler(void); /** * @} */ #include "core_cm0plus.h" #include "system_stm32l0xx.h" #include /** @addtogroup Peripheral_registers_structures * @{ */ /** * @brief Analog to Digital Converter */ typedef struct { __IO uint32_t ISR; /*!< ADC Interrupt and Status register, Address offset:0x00 */ __IO uint32_t IER; /*!< ADC Interrupt Enable register, Address offset:0x04 */ __IO uint32_t CR; /*!< ADC Control register, Address offset:0x08 */ __IO uint32_t CFGR1; /*!< ADC Configuration register 1, Address offset:0x0C */ __IO uint32_t CFGR2; /*!< ADC Configuration register 2, Address offset:0x10 */ __IO uint32_t SMPR; /*!< ADC Sampling time register, Address offset:0x14 */ uint32_t RESERVED1; /*!< Reserved, 0x18 */ uint32_t RESERVED2; /*!< Reserved, 0x1C */ __IO uint32_t TR; /*!< ADC watchdog threshold register, Address offset:0x20 */ uint32_t RESERVED3; /*!< Reserved, 0x24 */ __IO uint32_t CHSELR; /*!< ADC channel selection register, Address offset:0x28 */ uint32_t RESERVED4[5]; /*!< Reserved, 0x2C */ __IO uint32_t DR; /*!< ADC data register, Address offset:0x40 */ uint32_t RESERVED5[28]; /*!< Reserved, 0x44 - 0xB0 */ __IO uint32_t CALFACT; /*!< ADC data register, Address offset:0xB4 */ } ADC_TypeDef; typedef struct { __IO uint32_t CCR; } ADC_Common_TypeDef; /** * @brief Comparator */ typedef struct { __IO uint32_t CSR; /*!< COMP comparator control and status register, Address offset: 0x18 */ } COMP_TypeDef; /** * @brief CRC calculation unit */ typedef struct { __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */ __IO uint8_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */ uint8_t RESERVED0; /*!< Reserved, 0x05 */ uint16_t RESERVED1; /*!< Reserved, 0x06 */ __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ uint32_t RESERVED2; /*!< Reserved, 0x0C */ __IO uint32_t INIT; /*!< Initial CRC value register, Address offset: 0x10 */ __IO uint32_t POL; /*!< CRC polynomial register, Address offset: 0x14 */ } CRC_TypeDef; /** * @brief Clock Recovery System */ typedef struct { __IO uint32_t CR; /*!< CRS ccontrol register, Address offset: 0x00 */ __IO uint32_t CFGR; /*!< CRS configuration register, Address offset: 0x04 */ __IO uint32_t ISR; /*!< CRS interrupt and status register, Address offset: 0x08 */ __IO uint32_t ICR; /*!< CRS interrupt flag clear register, Address offset: 0x0C */ } CRS_TypeDef; /** * @brief Digital to Analog Converter */ typedef struct { __IO uint32_t CR; /*!< DAC control register, Address offset: 0x00 */ __IO uint32_t SWTRIGR; /*!< DAC software trigger register, Address offset: 0x04 */ __IO uint32_t DHR12R1; /*!< DAC channel1 12-bit right-aligned data holding register, Address offset: 0x08 */ __IO uint32_t DHR12L1; /*!< DAC channel1 12-bit left aligned data holding register, Address offset: 0x0C */ __IO uint32_t DHR8R1; /*!< DAC channel1 8-bit right aligned data holding register, Address offset: 0x10 */ uint32_t RESERVED0[6]; /*!< 0x14-0x28 */ __IO uint32_t DOR1; /*!< DAC channel1 data output register, Address offset: 0x2C */ uint32_t RESERVED1; /*!< 0x30 */ __IO uint32_t SR; /*!< DAC status register, Address offset: 0x34 */ } DAC_TypeDef; /** * @brief Debug MCU */ typedef struct { __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */ __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */ __IO uint32_t APB1FZ; /*!< Debug MCU APB1 freeze register, Address offset: 0x08 */ __IO uint32_t APB2FZ; /*!< Debug MCU APB2 freeze register, Address offset: 0x0C */ }DBGMCU_TypeDef; /** * @brief DMA Controller */ typedef struct { __IO uint32_t CCR; /*!< DMA channel x configuration register */ __IO uint32_t CNDTR; /*!< DMA channel x number of data register */ __IO uint32_t CPAR; /*!< DMA channel x peripheral address register */ __IO uint32_t CMAR; /*!< DMA channel x memory address register */ } DMA_Channel_TypeDef; typedef struct { __IO uint32_t ISR; /*!< DMA interrupt status register, Address offset: 0x00 */ __IO uint32_t IFCR; /*!< DMA interrupt flag clear register, Address offset: 0x04 */ } DMA_TypeDef; typedef struct { __IO uint32_t CSELR; /*!< DMA channel selection register, Address offset: 0xA8 */ } DMA_Request_TypeDef; /** * @brief External Interrupt/Event Controller */ typedef struct { __IO uint32_t IMR; /*!
© COPYRIGHT(c) 2014 STMicroelectronics
* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /** @addtogroup CMSIS * @{ */ /** @addtogroup stm32l0xx * @{ */ #ifndef __STM32L0xx_H #define __STM32L0xx_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** @addtogroup Library_configuration_section * @{ */ /* Uncomment the line below according to the target STM32 device used in your application */ #if !defined (STM32L051xx) && !defined (STM32L052xx) && !defined (STM32L053xx) && !defined (STM32L062xx) && \ !defined (STM32L063xx) && !defined (STM32L061xx) /* #define STM32L051xx */ /*!< STM32L051K8, STM32L051C6,STM32L051C8,STM32L051R6 and STM32L051R8 Devices */ /* #define STM32L052xx */ /*!< STM32L052K6, STM32L052K8,STM32L052C6,STM32L052C8,STM32L052R6 and STM32L052R8 Devices */ #define STM32L053xx /*!< STM32L053C6, STM32L053C8, STM32L053R6, and STM32L053R8 Devices */ /* #define STM32L062xx */ /*!< STM32L062K8 */ /* #define STM32L063xx */ /*!< STM32L063C8, STM32L063R8 */ /* #define STM32L061xx */ #endif /* Tip: To avoid modifying this file each time you need to switch between these devices, you can define the device in your toolchain compiler preprocessor. */ #if !defined (USE_HAL_DRIVER) /** * @brief Comment the line below if you will not use the peripherals drivers. In this case, these drivers will not be included and the application code will be based on direct access to peripherals registers */ /*#define USE_HAL_DRIVER */ #endif /* USE_HAL_DRIVER */ /** * @brief CMSIS Device version number V1.0.0RC1 */ #define __STM32L0xx_CMSIS_DEVICE_VERSION_MAIN (0x01) /*!< [31:24] main version */ #define __STM32L0xx_CMSIS_DEVICE_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */ #define __STM32L0xx_CMSIS_DEVICE_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ #define __STM32L0xx_CMSIS_DEVICE_VERSION_RC (0x01) /*!< [7:0] release candidate */ #define __STM32L0xx_CMSIS_DEVICE_VERSION ((__CMSIS_DEVICE_VERSION_MAIN << 24)\ |(__CMSIS_DEVICE_HAL_VERSION_SUB1 << 16)\ |(__CMSIS_DEVICE_HAL_VERSION_SUB2 << 8 )\ |(__CMSIS_DEVICE_HAL_VERSION_RC)) /** * @} */ /** @addtogroup Device_Included * @{ */ #if defined(STM32L051xx) #include "stm32l051xx.h" #elif defined(STM32L052xx) #include "stm32l052xx.h" #elif defined(STM32L053xx) #include "stm32l053xx.h" #elif defined(STM32L062xx) #include "stm32l062xx.h" #elif defined(STM32L063xx) #include "stm32l063xx.h" #elif defined(STM32L061xx) #include "stm32l061xx.h" #else #error "Please select first the target STM32L0xx device used in your application (in stm32l0xx.h file)" #endif /** * @} */ /** @addtogroup Exported_types * @{ */ typedef enum { RESET = 0, SET = !RESET } FlagStatus, ITStatus; typedef enum { DISABLE = 0, ENABLE = !DISABLE } FunctionalState; #define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) typedef enum { ERROR = 0, SUCCESS = !ERROR } ErrorStatus; /** * @} */ /** @addtogroup Exported_macro * @{ */ #define SET_BIT(REG, BIT) ((REG) |= (BIT)) #define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT)) #define READ_BIT(REG, BIT) ((REG) & (BIT)) #define CLEAR_REG(REG) ((REG) = (0x0)) #define WRITE_REG(REG, VAL) ((REG) = (VAL)) #define READ_REG(REG) ((REG)) #define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK))) /** * @} */ #if defined (USE_HAL_DRIVER) #include "stm32l0xx_hal.h" #endif /* USE_HAL_DRIVER */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __STM32L0xx_H */ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: 3rd_party/nucleo-l053r8/system_stm32l0xx.c ================================================ /** ****************************************************************************** * @file system_stm32l0xx.c * @author MCD Application Team * @version V1.0.0RC1 * @date 15-April-2014 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Source File. * * This file provides two functions and one global variable to be called from * user application: * - SystemInit(): This function is called at startup just after reset and * before branch to main program. This call is made inside * the "startup_stm32l0xx.s" file. * * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used * by the user application to setup the SysTick * timer or configure other parameters. * * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must * be called whenever the core clock is changed * during program execution. * * ****************************************************************************** * @attention * *

© COPYRIGHT(c) 2014 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /** @addtogroup CMSIS * @{ */ /** @addtogroup stm32l0xx_system * @{ */ /** @addtogroup STM32L0xx_System_Private_Includes * @{ */ #include "stm32l0xx.h" #if !defined (HSE_VALUE) #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (MSI_VALUE) #define MSI_VALUE ((uint32_t)2000000) /*!< Value of the Internal oscillator in Hz*/ #endif /* MSI_VALUE */ #if !defined (HSI_VALUE) #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @} */ /** @addtogroup STM32L0xx_System_Private_TypesDefinitions * @{ */ /** * @} */ /** @addtogroup STM32L0xx_System_Private_Defines * @{ */ /************************* Miscellaneous Configuration ************************/ /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ /* #define VECT_TAB_SRAM */ #define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ /******************************************************************************/ /** * @} */ /** @addtogroup STM32L0xx_System_Private_Macros * @{ */ /** * @} */ /** @addtogroup STM32L0xx_System_Private_Variables * @{ */ /* This variable is updated in three ways: * 1) by calling CMSIS function SystemCoreClockUpdate() * 2) by calling HAL API function HAL_RCC_GetSysClockFreq() * 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency * Note: If you use this function to configure the system clock; then there * is no need to call the 2 first functions listed above, since SystemCoreClock * variable is updated automatically. */ uint32_t SystemCoreClock = 2000000; __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; __I uint8_t PLLMulTable[9] = {3, 4, 6, 8, 12, 16, 24, 32, 48}; /** * @} */ /** @addtogroup STM32L0xx_System_Private_FunctionPrototypes * @{ */ /** * @} */ /** @addtogroup STM32L0xx_System_Private_Functions * @{ */ /** * @brief Setup the microcontroller system. * @param None * @retval None */ void SystemInit (void) { /*!< Set MSION bit */ RCC->CR |= (uint32_t)0x00000100; /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ RCC->CFGR &= (uint32_t)0x88FF400C; /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */ RCC->CR &= (uint32_t)0xFEF6FFF6; /*!< Reset HSI48ON bit */ RCC->CRRCR &= (uint32_t)0xFFFFFFFE; /*!< Reset HSEBYP bit */ RCC->CR &= (uint32_t)0xFFFBFFFF; /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */ RCC->CFGR &= (uint32_t)0xFF02FFFF; /*!< Disable all interrupts */ RCC->CIER = 0x00000000; /* Configure the Vector Table location add offset address ------------------*/ #ifdef VECT_TAB_SRAM SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ #else SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ #endif } /** * @brief Update SystemCoreClock according to Clock Register Values * The SystemCoreClock variable contains the core clock (HCLK), it can * be used by the user application to setup the SysTick timer or configure * other parameters. * * @note Each time the core clock (HCLK) changes, this function must be called * to update SystemCoreClock variable value. Otherwise, any configuration * based on this variable will be incorrect. * * @note - The system frequency computed by this function is not the real * frequency in the chip. It is calculated based on the predefined * constant and the selected clock source: * * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI * value as defined by the MSI range. * * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) * * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) * * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) * or HSI_VALUE(*) multiplied/divided by the PLL factors. * * (*) HSI_VALUE is a constant defined in stm32l0xx_hal.h file (default value * 16 MHz) but the real value may vary depending on the variations * in voltage and temperature. * * (**) HSE_VALUE is a constant defined in stm32l0xx_hal.h file (default value * 8 MHz), user has to ensure that HSE_VALUE is same as the real * frequency of the crystal used. Otherwise, this function may * have wrong result. * * - The result of this function could be not correct when using fractional * value for HSE crystal. * @param None * @retval None */ void SystemCoreClockUpdate (void) { uint32_t tmp = 0, pllmul = 0, plldiv = 0, pllsource = 0, msirange = 0; /* Get SYSCLK source -------------------------------------------------------*/ tmp = RCC->CFGR & RCC_CFGR_SWS; switch (tmp) { case 0x00: /* MSI used as system clock */ SystemCoreClock = ((1 <<((RCC->ICSCR & RCC_ICSCR_MSIRANGE)>>13 ))* 64000); break; case 0x04: /* HSI used as system clock */ SystemCoreClock = HSI_VALUE; break; case 0x08: /* HSE used as system clock */ SystemCoreClock = HSE_VALUE; break; case 0x0C: /* PLL used as system clock */ /* Get PLL clock source and multiplication factor ----------------------*/ pllmul = RCC->CFGR & RCC_CFGR_PLLMUL; plldiv = RCC->CFGR & RCC_CFGR_PLLDIV; pllmul = PLLMulTable[(pllmul >> 18)]; plldiv = (plldiv >> 22) + 1; pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; if (pllsource == 0x00) { /* HSI oscillator clock selected as PLL clock entry */ SystemCoreClock = (((HSI_VALUE) * pllmul) / plldiv); } else { /* HSE selected as PLL clock entry */ SystemCoreClock = (((HSE_VALUE) * pllmul) / plldiv); } break; default: /* MSI used as system clock */ msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13; SystemCoreClock = (32768 * (1 << (msirange + 1))); break; } /* Compute HCLK clock frequency --------------------------------------------*/ /* Get HCLK prescaler */ tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; /* HCLK clock frequency */ SystemCoreClock >>= tmp; } /** * @} */ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: 3rd_party/nucleo-l053r8/system_stm32l0xx.c.pll ================================================ /** ****************************************************************************** * @file system_stm32l0xx.c * @author MCD Application Team * @version V1.0.0RC1 * @date 15-April-2014 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Source File. * * This file provides two functions and one global variable to be called from * user application: * - SystemInit(): This function is called at startup just after reset and * before branch to main program. This call is made inside * the "startup_stm32l0xx.s" file. * * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used * by the user application to setup the SysTick * timer or configure other parameters. * * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must * be called whenever the core clock is changed * during program execution. * * ****************************************************************************** * @attention * *

© COPYRIGHT(c) 2014 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /** @addtogroup CMSIS * @{ */ /** @addtogroup stm32l0xx_system * @{ */ /** @addtogroup STM32L0xx_System_Private_Includes * @{ */ #include "stm32l0xx.h" #if !defined (HSE_VALUE) #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (MSI_VALUE) #define MSI_VALUE ((uint32_t)2000000) /*!< Value of the Internal oscillator in Hz*/ #endif /* MSI_VALUE */ #if !defined (HSI_VALUE) #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @brief In the following line adjust the External High Speed oscillator (HSE) Startup Timeout value */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT ((uint16_t)0x5000) /*!< Time out for HSE start up */ #endif /** * @brief In the following line adjust the Internal High Speed oscillator (HSI) Startup Timeout value */ #if !defined (HSI_STARTUP_TIMEOUT) #define HSI_STARTUP_TIMEOUT ((uint16_t)0x5000) /*!< Time out for HSI start up */ #endif /** * @} */ /** @addtogroup STM32L0xx_System_Private_TypesDefinitions * @{ */ /** * @} */ /** @addtogroup STM32L0xx_System_Private_Defines * @{ */ /************************* Miscellaneous Configuration ************************/ /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ /* #define VECT_TAB_SRAM */ #define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ /******************************************************************************/ /** * @} */ /** @addtogroup STM32L0xx_System_Private_Macros * @{ */ /** * @} */ /** @addtogroup STM32L0xx_System_Private_Variables * @{ */ /* This variable is updated in three ways: 1) by calling CMSIS function SystemCoreClockUpdate() 2) by calling HAL API function HAL_RCC_GetHCLKFreq() 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency Note: If you use this function to configure the system clock; then there is no need to call the 2 first functions listed above, since SystemCoreClock variable is updated automatically. */ uint32_t SystemCoreClock = 2000000; __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; __I uint8_t PLLMulTable[9] = {3, 4, 6, 8, 12, 16, 24, 32, 48}; /** * @} */ /** @addtogroup STM32L0xx_System_Private_FunctionPrototypes * @{ */ static void SetSysClock(void); /** * @} */ /** @addtogroup STM32L0xx_System_Private_Functions * @{ */ /** * @brief Setup the microcontroller system. * @param None * @retval None */ void SystemInit (void) { /*!< Set MSION bit */ RCC->CR |= (uint32_t)0x00000100; /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ RCC->CFGR &= (uint32_t) 0x88FF400C; /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */ RCC->CR &= (uint32_t)0xFEF6FFF6; /*!< Reset HSI48ON bit */ RCC->CRRCR &= (uint32_t)0xFFFFFFFE; /*!< Reset HSEBYP bit */ RCC->CR &= (uint32_t)0xFFFBFFFF; /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */ RCC->CFGR &= (uint32_t)0xFF02FFFF; /*!< Disable all interrupts */ RCC->CIER = 0x00000000; /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */ SetSysClock(); /* Configure the Vector Table location add offset address ------------------*/ #ifdef VECT_TAB_SRAM SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ #else SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ #endif } /** * @brief Update SystemCoreClock according to Clock Register Values * The SystemCoreClock variable contains the core clock (HCLK), it can * be used by the user application to setup the SysTick timer or configure * other parameters. * * @note Each time the core clock (HCLK) changes, this function must be called * to update SystemCoreClock variable value. Otherwise, any configuration * based on this variable will be incorrect. * * @note - The system frequency computed by this function is not the real * frequency in the chip. It is calculated based on the predefined * constant and the selected clock source: * * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI * value as defined by the MSI range. * * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) * * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) * * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) * or HSI_VALUE(*) multiplied/divided by the PLL factors. * * (*) HSI_VALUE is a constant defined in stm32l0xx_hal.h file (default value * 16 MHz) but the real value may vary depending on the variations * in voltage and temperature. * * (**) HSE_VALUE is a constant defined in stm32l0xx_hal.h file (default value * 8 MHz), user has to ensure that HSE_VALUE is same as the real * frequency of the crystal used. Otherwise, this function may * have wrong result. * * - The result of this function could be not correct when using fractional * value for HSE crystal. * @param None * @retval None */ void SystemCoreClockUpdate (void) { uint32_t tmp = 0, pllmul = 0, plldiv = 0, pllsource = 0, msirange = 0; /* Get SYSCLK source -------------------------------------------------------*/ tmp = RCC->CFGR & RCC_CFGR_SWS; switch (tmp) { case 0x00: /* MSI used as system clock */ SystemCoreClock = ((1 <<((RCC->ICSCR & RCC_ICSCR_MSIRANGE)>>13 ))* 64000); break; case 0x04: /* HSI used as system clock */ SystemCoreClock = HSI_VALUE; break; case 0x08: /* HSE used as system clock */ SystemCoreClock = HSE_VALUE; break; case 0x0C: /* PLL used as system clock */ /* Get PLL clock source and multiplication factor ----------------------*/ pllmul = RCC->CFGR & RCC_CFGR_PLLMUL; plldiv = RCC->CFGR & RCC_CFGR_PLLDIV; pllmul = PLLMulTable[(pllmul >> 18)]; plldiv = (plldiv >> 22) + 1; pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; if (pllsource == 0x00) { /* HSI oscillator clock selected as PLL clock entry */ SystemCoreClock = (((HSI_VALUE) * pllmul) / plldiv); } else { /* HSE selected as PLL clock entry */ SystemCoreClock = (((HSE_VALUE) * pllmul) / plldiv); } break; default: /* MSI used as system clock */ msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13; SystemCoreClock = (32768 * (1 << (msirange + 1))); break; } /* Compute HCLK clock frequency --------------------------------------------*/ /* Get HCLK prescaler */ tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; /* HCLK clock frequency */ SystemCoreClock >>= tmp; } /** * @brief Configures the System clock frequency, AHB/APBx prescalers and Flash * settings. * @note This function should be called only once the RCC clock configuration * is reset to the default reset state (done in SystemInit() function). * @param None * @retval None * * This file configures the system clock as follows: *============================================================================= * System Clock Configuration *============================================================================= * System Clock source | PLL(HSE) *----------------------------------------------------------------------------- * SYSCLK | 32000000 Hz *----------------------------------------------------------------------------- * HCLK | 32000000 Hz *----------------------------------------------------------------------------- * AHB Prescaler | 1 *----------------------------------------------------------------------------- * APB1 Prescaler | 1 *----------------------------------------------------------------------------- * APB2 Prescaler | 1 *----------------------------------------------------------------------------- * HSE Frequency | 8000000 Hz *----------------------------------------------------------------------------- * PLL DIV | 3 *----------------------------------------------------------------------------- * PLL MUL | 12 *----------------------------------------------------------------------------- * VDD | 3.3 V *----------------------------------------------------------------------------- * Vcore | 1.8 V (Range 1) *----------------------------------------------------------------------------- * Flash Latency | 1 WS *----------------------------------------------------------------------------- * SDIO clock (SDIOCLK) | 48000000 Hz *----------------------------------------------------------------------------- * Require 48MHz for USB clock | Disabled *----------------------------------------------------------------------------- *============================================================================= */ static void SetSysClock(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ /* Enable HSE */ RCC->CR |= ((uint32_t)RCC_CR_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CR & RCC_CR_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CR & RCC_CR_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* Enable 64-bit access */ //???FLASH->ACR |= FLASH_ACR_ACC64; /* Enable Prefetch Buffer */ FLASH->ACR |= FLASH_ACR_PRFTEN; /* Flash 1 wait state */ FLASH->ACR |= FLASH_ACR_LATENCY; /* Power enable */ RCC->APB1ENR |= RCC_APB1ENR_PWREN; /* Select the Voltage Range 1 (1.8 V) */ PWR->CR = PWR_CR_VOS_0; /* Wait Until the Voltage Regulator is ready */ while((PWR->CSR & PWR_CSR_VOSF) != RESET) { } /* HCLK = SYSCLK /1*/ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; /* PCLK2 = HCLK /1*/ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; /* PCLK1 = HCLK /1*/ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; /* PLL configuration */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL | RCC_CFGR_PLLDIV)); //RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMUL12 | RCC_CFGR_PLLDIV3); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMUL4 | RCC_CFGR_PLLDIV4); /* Enable PLL */ RCC->CR |= RCC_CR_PLLON; /* Wait till PLL is ready */ while((RCC->CR & RCC_CR_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL) { } } else { /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */ } } /** * @} */ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: 3rd_party/nucleo-l053r8/system_stm32l0xx.h ================================================ /** ****************************************************************************** * @file system_stm32l0xx.h * @author MCD Application Team * @version V1.0.0RC1 * @date 15-April-2014 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Header File. ****************************************************************************** * @attention * *

© COPYRIGHT(c) 2014 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /** @addtogroup CMSIS * @{ */ /** @addtogroup stm32l0xx_system * @{ */ /** * @brief Define to prevent recursive inclusion */ #ifndef __SYSTEM_STM32L0XX_H #define __SYSTEM_STM32L0XX_H #ifdef __cplusplus extern "C" { #endif /** @addtogroup STM32L0xx_System_Includes * @{ */ /** * @} */ /** @addtogroup STM32L1xx_System_Exported_types * @{ */ /* This variable is updated in three ways: * 1) by calling CMSIS function SystemCoreClockUpdate() * 2) by calling HAL API function HAL_RCC_GetSysClockFreq() * 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency * Note: If you use this function to configure the system clock; then there * is no need to call the 2 first functions listed above, since SystemCoreClock * variable is updated automatically. */ extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ /** * @} */ /** @addtogroup STM32L0xx_System_Exported_Constants * @{ */ /** * @} */ /** @addtogroup STM32L0xx_System_Exported_Macros * @{ */ /** * @} */ /** @addtogroup STM32L0xx_System_Exported_Functions * @{ */ extern void SystemInit(void); extern void SystemCoreClockUpdate(void); /** * @} */ #ifdef __cplusplus } #endif #endif /*__SYSTEM_STM32L0XX_H */ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: FreeRTOS-comparison/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.15) # User is responsible to set two mandatory options: # FREERTOS_CONFIG_FILE_DIRECTORY # FREERTOS_PORT # # User can choose which heap implementation to use (either the implementations # included with FreeRTOS [1..5] or a custom implementation ) by providing the # option FREERTOS_HEAP. If the option is not set, the cmake will default to # using heap_4.c. # Absolute path to FreeRTOS config file directory set(FREERTOS_CONFIG_FILE_DIRECTORY "" CACHE STRING "Absolute path to the directory with FreeRTOSConfig.h") if(NOT FREERTOS_CONFIG_FILE_DIRECTORY) message(FATAL_ERROR " FreeRTOSConfig.h file directory not specified. Please specify absolute path to it from top-level CMake file:\n" " set(FREERTOS_CONFIG_FILE_DIRECTORY CACHE STRING \"\")\n" " or from CMake command line option:\n" " -DFREERTOS_CONFIG_FILE_DIRECTORY='/absolute_path/to/FreeRTOSConfig.h/directory'") elseif(NOT EXISTS ${FREERTOS_CONFIG_FILE_DIRECTORY}/FreeRTOSConfig.h) message(FATAL_ERROR " FreeRTOSConfig.h file not found in the directory specified (${FREERTOS_CONFIG_FILE_DIRECTORY})\n" " Please specify absolute path to it from top-level CMake file:\n" " set(FREERTOS_CONFIG_FILE_DIRECTORY CACHE STRING \"\")\n" " or from CMake command line option:\n" " -DFREERTOS_CONFIG_FILE_DIRECTORY='/absolute_path/to/FreeRTOSConfig.h/directory'") endif() # Heap number or absolute path to custom heap implementation provided by user set(FREERTOS_HEAP "4" CACHE STRING "FreeRTOS heap model number. 1 .. 5. Or absolute path to custom heap source file") # FreeRTOS port option set(FREERTOS_PORT "" CACHE STRING "FreeRTOS port name") if(NOT FREERTOS_PORT) message(FATAL_ERROR " FREERTOS_PORT is not set. Please specify it from top-level CMake file (example):\n" " set(FREERTOS_PORT GCC_ARM_CM4F CACHE STRING \"\")\n" " or from CMake command line option:\n" " -DFREERTOS_PORT=GCC_ARM_CM4F\n" " \n" " Available port options:\n" " BCC_16BIT_DOS_FLSH186 - Compiller: BCC Target: 16 bit DOS Flsh186\n" " BCC_16BIT_DOS_PC - Compiller: BCC Target: 16 bit DOS PC\n" " CCS_ARM_CM3 - Compiller: CCS Target: ARM Cortex-M3\n" " CCS_ARM_CM4F - Compiller: CCS Target: ARM Cortex-M4 with FPU\n" " CCS_ARM_CR4 - Compiller: CCS Target: ARM Cortex-R4\n" " CCS_MSP430X - Compiller: CCS Target: MSP430X\n" " CODEWARRIOR_COLDFIRE_V1 - Compiller: CoreWarrior Target: ColdFire V1\n" " CODEWARRIOR_COLDFIRE_V2 - Compiller: CoreWarrior Target: ColdFire V2\n" " CODEWARRIOR_HCS12 - Compiller: CoreWarrior Target: HCS12\n" " GCC_ARM_CA9 - Compiller: GCC Target: ARM Cortex-A9\n" " GCC_ARM_CA53_64_BIT - Compiller: GCC Target: ARM Cortex-A53 64 bit\n" " GCC_ARM_CA53_64_BIT_SRE - Compiller: GCC Target: ARM Cortex-A53 64 bit SRE\n" " GCC_ARM_CM0 - Compiller: GCC Target: ARM Cortex-M0\n" " GCC_ARM_CM3 - Compiller: GCC Target: ARM Cortex-M3\n" " GCC_ARM_CM3_MPU - Compiller: GCC Target: ARM Cortex-M3 with MPU\n" " GCC_ARM_CM4_MPU - Compiller: GCC Target: ARM Cortex-M4 with MPU\n" " GCC_ARM_CM4F - Compiller: GCC Target: ARM Cortex-M4 with FPU\n" " GCC_ARM_CM7 - Compiller: GCC Target: ARM Cortex-M7\n" " GCC_ARM_CM23_NONSECURE - Compiller: GCC Target: ARM Cortex-M23 non-secure\n" " GCC_ARM_CM23_SECURE - Compiller: GCC Target: ARM Cortex-M23 secure\n" " GCC_ARM_CM23_NTZ_NONSECURE - Compiller: GCC Target: ARM Cortex-M23 non-trustzone non-secure\n" " GCC_ARM_CM33_NONSECURE - Compiller: GCC Target: ARM Cortex-M33 non-secure\n" " GCC_ARM_CM33_SECURE - Compiller: GCC Target: ARM Cortex-M33 secure\n" " GCC_ARM_CM33_NTZ_NONSECURE - Compiller: GCC Target: ARM Cortex-M33 non-trustzone non-secure\n" " GCC_ARM_CM33_TFM - Compiller: GCC Target: ARM Cortex-M33 non-secure for TF-M\n" " GCC_ARM_CM55_NONSECURE - Compiller: GCC Target: ARM Cortex-M55 non-secure\n" " GCC_ARM_CM55_SECURE - Compiller: GCC Target: ARM Cortex-M55 secure\n" " GCC_ARM_CM55_NTZ_NONSECURE - Compiller: GCC Target: ARM Cortex-M55 non-trustzone non-secure\n" " GCC_ARM_CM55_TFM - Compiller: GCC Target: ARM Cortex-M55 non-secure for TF-M\n" " GCC_ARM_CM85_NONSECURE - Compiller: GCC Target: ARM Cortex-M85 non-secure\n" " GCC_ARM_CM85_SECURE - Compiller: GCC Target: ARM Cortex-M85 secure\n" " GCC_ARM_CM85_NTZ_NONSECURE - Compiller: GCC Target: ARM Cortex-M85 non-trustzone non-secure\n" " GCC_ARM_CM85_TFM - Compiller: GCC Target: ARM Cortex-M85 non-secure for TF-M\n" " GCC_ARM_CR5 - Compiller: GCC Target: ARM Cortex-R5\n" " GCC_ARM_CRX_NOGIC - Compiller: GCC Target: ARM Cortex-Rx no GIC\n" " GCC_ARM7_AT91FR40008 - Compiller: GCC Target: ARM7 Atmel AT91R40008\n" " GCC_ARM7_AT91SAM7S - Compiller: GCC Target: ARM7 Atmel AT91SAM7S\n" " GCC_ARM7_LPC2000 - Compiller: GCC Target: ARM7 LPC2000\n" " GCC_ARM7_LPC23XX - Compiller: GCC Target: ARM7 LPC23xx\n" " GCC_ATMEGA323 - Compiller: GCC Target: ATMega323\n" " GCC_AVR32_UC3 - Compiller: GCC Target: AVR32 UC3\n" " GCC_COLDFIRE_V2 - Compiller: GCC Target: ColdFire V2\n" " GCC_CORTUS_APS3 - Compiller: GCC Target: CORTUS APS3\n" " GCC_H8S2329 - Compiller: GCC Target: H8S2329\n" " GCC_HCS12 - Compiller: GCC Target: HCS12\n" " GCC_IA32_FLAT - Compiller: GCC Target: IA32 flat\n" " GCC_MICROBLAZE - Compiller: GCC Target: MicroBlaze\n" " GCC_MICROBLAZE_V8 - Compiller: GCC Target: MicroBlaze V8\n" " GCC_MICROBLAZE_V9 - Compiller: GCC Target: MicroBlaze V9\n" " GCC_MSP430F449 - Compiller: GCC Target: MSP430F449\n" " GCC_NIOSII - Compiller: GCC Target: NiosII\n" " GCC_PPC405_XILINX - Compiller: GCC Target: Xilinx PPC405\n" " GCC_PPC440_XILINX - Compiller: GCC Target: Xilinx PPC440\n" " GCC_RISC_V - Compiller: GCC Target: RISC-V\n" " GCC_RISC_V_PULPINO_VEGA_RV32M1RM - Compiller: GCC Target: RISC-V Pulpino Vega RV32M1RM\n" " GCC_RL78 - Compiller: GCC Target: Renesas RL78\n" " GCC_RX100 - Compiller: GCC Target: Renesas RX100\n" " GCC_RX200 - Compiller: GCC Target: Renesas RX200\n" " GCC_RX600 - Compiller: GCC Target: Renesas RX600\n" " GCC_RX600_V2 - Compiller: GCC Target: Renesas RX600 v2\n" " GCC_RX700_V3_DPFPU - Compiller: GCC Target: Renesas RX700 v3 with DPFPU\n" " GCC_STR75X - Compiller: GCC Target: STR75x\n" " GCC_TRICORE_1782 - Compiller: GCC Target: TriCore 1782\n" " GCC_ARC_EM_HS - Compiller: GCC Target: DesignWare ARC EM HS\n" " GCC_ARC_V1 - Compiller: GCC Target: DesignWare ARC v1\n" " GCC_ATMEGA - Compiller: GCC Target: ATmega\n" " GCC_POSIX - Compiller: GCC Target: Posix\n" " GCC_RP2040 - Compiller: GCC Target: RP2040 ARM Cortex-M0+\n" " GCC_XTENSA_ESP32 - Compiller: GCC Target: Xtensa ESP32\n" " GCC_AVRDX - Compiller: GCC Target: AVRDx\n" " GCC_AVR_MEGA0 - Compiller: GCC Target: AVR Mega0\n" " IAR_78K0K - Compiller: IAR Target: Renesas 78K0K\n" " IAR_ARM_CA5_NOGIC - Compiller: IAR Target: ARM Cortex-A5 no GIC\n" " IAR_ARM_CA9 - Compiller: IAR Target: ARM Cortex-A9\n" " IAR_ARM_CM0 - Compiller: IAR Target: ARM Cortex-M0\n" " IAR_ARM_CM3 - Compiller: IAR Target: ARM Cortex-M3\n" " IAR_ARM_CM4F - Compiller: IAR Target: ARM Cortex-M4 with FPU\n" " IAR_ARM_CM4F_MPU - Compiller: IAR Target: ARM Cortex-M4 with FPU and MPU\n" " IAR_ARM_CM7 - Compiller: IAR Target: ARM Cortex-M7\n" " IAR_ARM_CM23_NONSECURE - Compiller: IAR Target: ARM Cortex-M23 non-secure\n" " IAR_ARM_CM23_SECURE - Compiller: IAR Target: ARM Cortex-M23 secure\n" " IAR_ARM_CM23_NTZ_NONSECURE - Compiller: IAR Target: ARM Cortex-M23 non-trustzone non-secure\n" " IAR_ARM_CM33_NONSECURE - Compiller: IAR Target: ARM Cortex-M33 non-secure\n" " IAR_ARM_CM33_SECURE - Compiller: IAR Target: ARM Cortex-M33 secure\n" " IAR_ARM_CM33_NTZ_NONSECURE - Compiller: IAR Target: ARM Cortex-M33 non-trustzone non-secure\n" " IAR_ARM_CM55_NONSECURE - Compiller: IAR Target: ARM Cortex-M55 non-secure\n" " IAR_ARM_CM55_SECURE - Compiller: IAR Target: ARM Cortex-M55 secure\n" " IAR_ARM_CM55_NTZ_NONSECURE - Compiller: IAR Target: ARM Cortex-M55 non-trustzone non-secure\n" " IAR_ARM_CM85_NONSECURE - Compiller: IAR Target: ARM Cortex-M85 non-secure\n" " IAR_ARM_CM85_SECURE - Compiller: IAR Target: ARM Cortex-M85 secure\n" " IAR_ARM_CM85_NTZ_NONSECURE - Compiller: IAR Target: ARM Cortex-M85 non-trustzone non-secure\n" " IAR_ARM_CRX_NOGIC - Compiller: IAR Target: ARM Cortex-Rx no GIC\n" " IAR_ATMEGA323 - Compiller: IAR Target: ATMega323\n" " IAR_ATMEL_SAM7S64 - Compiller: IAR Target: Atmel SAM7S64\n" " IAR_ATMEL_SAM9XE - Compiller: IAR Target: Atmel SAM9XE\n" " IAR_AVR_AVRDX - Compiller: IAR Target: AVRDx\n" " IAR_AVR_MEGA0 - Compiller: IAR Target: AVR Mega0\n" " IAR_AVR32_UC3 - Compiller: IAR Target: AVR32 UC3\n" " IAR_LPC2000 - Compiller: IAR Target: LPC2000\n" " IAR_MSP430 - Compiller: IAR Target: MSP430\n" " IAR_MSP430X - Compiller: IAR Target: MSP430X\n" " IAR_RISC_V - Compiller: IAR Target: RISC-V\n" " IAR_RL78 - Compiller: IAR Target: Renesas RL78\n" " IAR_RX100 - Compiller: IAR Target: Renesas RX100\n" " IAR_RX600 - Compiller: IAR Target: Renesas RX600\n" " IAR_RX700_V3_DPFPU - Compiller: IAR Target: Renesas RX700 v3 with DPFPU\n" " IAR_RX_V2 - Compiller: IAR Target: Renesas RX v2\n" " IAR_STR71X - Compiller: IAR Target: STR71x\n" " IAR_STR75X - Compiller: IAR Target: STR75x\n" " IAR_STR91X - Compiller: IAR Target: STR91x\n" " IAR_V850ES_FX3 - Compiller: IAR Target: Renesas V850ES/Fx3\n" " IAR_V850ES_HX3 - Compiller: IAR Target: Renesas V850ES/Hx3\n" " MIKROC_ARM_CM4F - Compiller: MikroC Target: ARM Cortex-M4 with FPU\n" " MPLAB_PIC18F - Compiller: MPLAB Target: PIC18F\n" " MPLAB_PIC24 - Compiller: MPLAB Target: PIC24\n" " MPLAB_PIC32MEC14XX - Compiller: MPLAB Target: PIC32MEC14xx\n" " MPLAB_PIC32MX - Compiller: MPLAB Target: PIC32MX\n" " MPLAB_PIC32MZ - Compiller: MPLAB Target: PIC32MZ\n" " MSVC_MINGW - Compiller: MSVC or MinGW Target: x86\n" " OWATCOM_16BIT_DOS_FLSH186 - Compiller: Open Watcom Target: 16 bit DOS Flsh186\n" " OWATCOM_16BIT_DOS_PC - Compiller: Open Watcom Target: 16 bit DOS PC\n" " PARADIGM_TERN_EE_LARGE - Compiller: Paradigm Target: Tern EE large\n" " PARADIGM_TERN_EE_SMALL - Compiller: Paradigm Target: Tern EE small\n" " RENESAS_RX100 - Compiller: Renesas Target: RX100\n" " RENESAS_RX200 - Compiller: Renesas Target: RX200\n" " RENESAS_RX600 - Compiller: Renesas Target: RX600\n" " RENESAS_RX600_V2 - Compiller: Renesas Target: RX600 v2\n" " RENESAS_RX700_V3_DPFPU - Compiller: Renesas Target: RX700 v3 with DPFPU\n" " RENESAS_SH2A_FPU - Compiller: Renesas Target: SH2A with FPU\n" " ROWLEY_MSP430F449 - Compiller: Rowley Target: MSP430F449\n" " RVDS_ARM_CA9 - Compiller: RVDS Target: ARM Cortex-A9\n" " RVDS_ARM_CM0 - Compiller: RVDS Target: ARM Cortex-M0\n" " RVDS_ARM_CM3 - Compiller: RVDS Target: ARM Cortex-M3\n" " RVDS_ARM_CM4_MPU - Compiller: RVDS Target: ARM Cortex-M4 with MPU\n" " RVDS_ARM_CM4F - Compiller: RVDS Target: ARM Cortex-M4 with FPU\n" " RVDS_ARM_CM7 - Compiller: RVDS Target: ARM Cortex-M7\n" " RVDS_ARM7_LPC21XX - Compiller: RVDS Target: ARM7 LPC21xx\n" " SDCC_CYGNAL - Compiller: SDCC Target: Cygnal\n" " SOFTUNE_MB91460 - Compiller: Softune Target: MB91460\n" " SOFTUNE_MB96340 - Compiller: Softune Target: MB96340\n" " TASKING_ARM_CM4F - Compiller: Tasking Target: ARM Cortex-M4 with FPU\n" " CDK_THEAD_CK802 - Compiller: CDK Target: T-head CK802\n" " XCC_XTENSA - Compiller: XCC Target: Xtensa\n" " WIZC_PIC18 - Compiller: WizC Target: PIC18") endif() add_subdirectory(portable) add_library(freertos_kernel STATIC croutine.c event_groups.c list.c queue.c stream_buffer.c tasks.c timers.c # If FREERTOS_HEAP is digit between 1 .. 5 - it is heap number, otherwise - it is path to custom heap source file $>,${FREERTOS_HEAP},portable/MemMang/heap_${FREERTOS_HEAP}.c> ) target_include_directories(freertos_kernel PUBLIC include ${FREERTOS_CONFIG_FILE_DIRECTORY} ) target_link_libraries(freertos_kernel freertos_kernel_port) ================================================ FILE: FreeRTOS-comparison/GitHub-FreeRTOS-Kernel-Home.url ================================================ [{000214A0-0000-0000-C000-000000000046}] Prop3=19,2 [InternetShortcut] URL=https://github.com/FreeRTOS/FreeRTOS-Kernel IconIndex=0 IDList= HotKey=0 ================================================ FILE: FreeRTOS-comparison/History.txt ================================================ Documentation and download available at https://www.FreeRTOS.org/ Changes between FreeRTOS V10.5.0 and FreeRTOS V10.5.1 released November 16 2022 + Updating the version in the manifest.yml file to be accurate. Changes between FreeRTOS V10.4.6 and FreeRTOS V10.5.0 released September 16 2022 + ARMv7-M and ARMv8-M MPU ports: It was possible for a third party that already independently gained the ability to execute injected code to read from or write to arbitrary addresses by passing a negative argument as the xIndex parameter to pvTaskGetThreadLocalStoragePointer() or vTaskSetThreadLocalStoragePointer respectively. A check has been added to ensure that passing a negative argument as the xIndex parameter does not cause arbitrary read or write. We thank Certibit Consulting, LLC for reporting this issue. + ARMv7-M and ARMv8-M MPU ports: It was possible for an unprivileged task to invoke any function with privilege by passing it as a parameter to MPU_xTaskCreate, MPU_xTaskCreateStatic, MPU_xTimerCreate, MPU_xTimerCreateStatic, or MPU_xTimerPendFunctionCall. MPU_xTaskCreate and MPU_xTaskCreateStatic have been updated to only allow creation of unprivileged tasks. MPU_xTimerCreate, MPU_xTimerCreateStatic and MPU_xTimerPendFunctionCall APIs have been removed. We thank Huazhong University of Science and Technology for reporting this issue. + ARMv7-M and ARMv8-M MPU ports: It was possible for a third party that already independently gained the ability to execute injected code to achieve further privilege escalation by branching directly inside a FreeRTOS MPU API wrapper function with a manually crafted stack frame. The local stack variable `xRunningPrivileged` has been removed so that a manually crafted stack frame cannot be used for privilege escalation by branching directly inside a FreeRTOS MPU API wrapper. We thank Certibit Consulting, LLC, Huazhong University of Science and Technology and the SecLab team at Northeastern University for reporting this issue. + ARMv7-M MPU ports: It was possible to configure overlapping memory protection unit (MPU) regions such that an unprivileged task could access privileged data. The kernel now uses highest numbered MPU regions for kernel protections to prevent such MPU configurations. We thank the SecLab team at Northeastern University for reporting this issue. + Add support for ARM Cortex-M55. + Add support for ARM Cortex-M85. Contributed by @gbrtth. + Add vectored mode interrupt support to the RISC-V port. + Add support for RV32E extension (Embedded Profile) in RISC-V GCC port. Contributed by @Limoto. + Heap improvements: - Add a check to heap_2 to track if a memory block is allocated to the application or not. The MSB of the size field is used for this purpose. The same check already exists in heap_4 and heap_5. This check prevents double free errors. - Add a new flag configHEAP_CLEAR_MEMORY_ON_FREE to heap_2, heap_4 and heap_5. If the flag is set in FreeRTOSConfig.h then memory freed using vPortFree() is automatically cleared to zero. - Add a new API pvPortCalloc to heap_2, heap_4 and heap_5 which has the same signature as the standard library calloc function. - Update the pointer types to portPOINTER_SIZE_TYPE. Contributed by @Octaviarius. + Add the ability to override send and receive completed callbacks for each instance of a stream buffer or message buffer. Earlier there could be one send and one receive callback for all instances of stream and message buffers. Having separate callbacks per instance allows different message and stream buffers to be used differently - for example, some for inter core communication and others for same core communication. The feature can be controlled by setting the configuration option configUSE_SB_COMPLETED_CALLBACK in FreeRTOSConfig.h. When the option is set to 1, APIs xStreamBufferCreateWithCallback() or xStreamBufferCreateStaticWithCallback() (and likewise APIs for message buffer) can be used to create a stream buffer or message buffer instance with application provided callback overrides. When the option is set to 0, then the default callbacks as defined by sbSEND_COMPLETED() and sbRECEIVE_COMPLETED() macros are invoked. To maintain backwards compatibility, configUSE_SB_COMPLETED_CALLBACK defaults to 0. The functionality is currently not supported for MPU enabled ports. + Generalize the FreeRTOS's Thread Local Storage (TLS) support so that it is not tied to newlib and can be used with other c-runtime libraries also. The default behavior for newlib support is kept same for backward compatibility. + Add support to build and link FreeRTOS using CMake build system. Contributed by @yhsb2k. + Add support to generate Software Bill of Materials (SBOM) for every release. + Add support for 16 MPU regions to the GCC Cortex-M33 ports. + Add ARM Cortex-M7 r0p0/r0p1 Errata 837070 workaround to ARM CM4 MPU ports. The application writer needs to define configENABLE_ERRATA_837070_WORKAROUND when using CM4 MPU ports on a Cortex-M7 r0p0/r0p1 core. + Add configSYSTICK_CLOCK_HZ to Cortex-M0 ports. This is needed to support the case when the SysTick timer is not clocked from the same source as the CPU. + Add hardware stack protection support to MicroBlazeV9 port. This ensures that the CPU immediately raises Stack Protection Violation exception as soon as any task violates its stack limits. Contributed by @uecasm. + Introduce the configUSE_MINI_LIST_ITEM configuration option. When this option is set to 1, ListItem_t and MiniLitItem_t remain separate types. However, when configUSE_MINI_LIST_ITEM == 0, MiniLitItem_t and ListItem_t are both typedefs of the same struct xLIST_ITEM. This addresses some issues observed when strict-aliasing and link time optimization are enabled. To maintain backwards compatibility, configUSE_MINI_LIST_ITEM defaults to 1. + Simplify prvInitialiseNewTask to memset newly allocated TCB structures to zero, and remove code that set individual structure members to zero. + Add prototype for prvPortYieldFromISR to the POSIX port so that it builds without any warning with -Wmissing-prototypes compiler option. + Add top of stack and end of stack to the task info report obtained using vTaskGetInfo(). Contributed by @shreyasbharath. + Add a cap to the cRxLock and cTxLock members of the queue data structure. These locks count the number items received and sent to the queue while the queue was locked. These are later used to unblock tasks waiting on the queue when the queue is unlocked. This PR caps the values of the cRxLock and cTxLock to the number of tasks in the system because we cannot unblock more tasks than there are in the system. Note that the same assert could still be triggered is the application creates more than 127 tasks. + Changed uxAutoReload parameter in timer functions to xAutoReload. The type is now BaseType_t. This matches the type of pdTRUE and pdFALSE. The new function xTimerGetAutoReload() provides the auto-reload state as a BaseType_t. The legacy function uxTimerGetAutoReload is retained with the original UBaseType_t return value. + Fix support for user implementations of tickless idle that call vTaskStepTick() with xExpectedIdleTime ticks to step. The new code ensures xTickCount reaches xNextTaskUnblockTime inside xTaskIncrementTick() instead of inside vTaskStepTick(). This fixes the typical case where a task wakes up one tick late and a rare case assertion failure when xTickCount\ rolls over. Contributed by @jefftenney. + Fix deadlock in event groups when pvPortMalloc and vPortFree functions are protected with a mutex. Contributed by @clemenskresser. + Fix a warning in tasks.c when compiled with -Wduplicated-branches GCC option. Contributed by @pierrenoel-bouteville-act. + Fix compilation error in tasks.c when configSUPPORT_DYNAMIC_ALLOCATION is set to zero. Contributed by @rdpoor. + Fix prvWriteMessageToBuffer() function in stream_buffer.c so that it correctly copies length on big endian platforms too. + Remove the need for INCLUDE_vTaskSuspend to be set to 1 when configUSE_TICKLESS_IDLE is enabled. Contributed by @pramithkv. + Update the RL78 IAR port to the latest version of IAR which uses the industry standard ELF format as opposed to earlier UBROF object format. Contributed by @felipe-iar. + Add tick type is atomic flag when tick count is 16-bit to PIC24 port. This allows the PIC24 family of 16 bit processors to read the tick count without a critical section when the tick count is also 16 bits. + Fix offset-out-of-range errors for GCC CM3/CM4 mpu ports when Link Time Optimization is enabled. Contributed by @niniemann. + Remove #error when RISC-V port is compiled on a 64-bit RISC-V platform. Contributed by @cmdrf. + Fix ullPortInterruptNesting alignment in Cortex-A53 port so that it is 8-byte aligned. This fixes the unaligned access exception. Contributed by @Atomar25. + Fix Interrupt Handler Register Function and Exception Process in NiosII Port. Contributed by @ghost. + Change FreeRTOS IRQ Handler for Cortex-A53 SRE port to store and restore interrupt acknowledge register. This ensures that the SRE port behavior matches the Memory Mapped IO port. Contributed by @sviaunxp. + Update the uncrustify config file to match the version of the uncrustify used in the CI Action. Also, pin the version of uncrustify in CI. Contributed by @swaldhoer. Changes between FreeRTOS V10.4.5 and FreeRTOS V10.4.6 released November 12 2021 + ARMv7-M and ARMv8-M MPU ports – prevent non-kernel code from calling the internal functions xPortRaisePrivilege and vPortResetPrivilege by changing them to macros. + Introduce a new config configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS which enables developers to prevent critical sections from unprivileged tasks. It defaults to 1 for backward compatibility. Application should set it to 0 to disable critical sections from unprivileged tasks. Changes between FreeRTOS V10.4.4 and FreeRTOS V10.4.5 released September 10 2021 See https://www.FreeRTOS.org/FreeRTOS-V10.4.5.html + Introduce configRUN_TIME_COUNTER_TYPE which enables developers to define the type used to hold run time statistic counters. Defaults to uint32_t for backward compatibility. #define configRUN_TIME_COUNTER_TYPE to a type (for example, uint64_t) in FreeRTOSConfig.h to override the default. + Introduce ulTaskGetIdleRunTimePercent() to complement the pre-existing ulTaskGetIdleRunTimeCounter(). Whereas the pre-existing function returns the raw run time counter value, the new function returns the percentage of the entire run time consumed by the idle task. Note the amount of idle time is only a good measure of the slack time in a system if there are no other tasks executing at the idle priority, tickless idle is not used, and configIDLE_SHOULD_YIELD is set to 0. + ARMv8-M secure-side port: Tasks that call secure functions from the non-secure side of an ARMv8-M MCU (ARM Cortex-M23 and Cortex-M33) have two contexts - one on the non-secure side and one on the secure-side. Previous versions of the FreeRTOS ARMv8-M secure-side ports allocated the structures that reference secure-side contexts at run time. Now the structures are allocated statically at compile time. The change necessitates the introduction of the secureconfigMAX_SECURE_CONTEXTS configuration constant, which sets the number of statically allocated secure contexts. secureconfigMAX_SECURE_CONTEXTS defaults to 8 if left undefined. Applications that only use FreeRTOS code on the non-secure side, such as those running third-party code on the secure side, are not affected by this change. Changes between FreeRTOS V10.4.3 and FreeRTOS V10.4.4 released May 28 2021 + Minor performance improvements to xTaskIncrementTick() achieved by providing macro versions of uxListRemove() and vListInsertEnd(). + Minor refactor of timers.c that obsoletes the need for the tmrCOMMAND_START_DONT_TRACE macro and removes the need for timers.c to post to its own event queue. A consequence of this change is that auto- reload timers that miss their intended next execution time will execute again immediately rather than executing again the next time the command queue is processed. (thanks Jeff Tenney). + Fix a race condition in the message buffer implementation. The underlying cause was that length and data bytes are written and read as two distinct operations, which both modify the size of the buffer. If a context switch occurs after adding or removing the length bytes, but before adding or removing the data bytes, then another task may observe the message buffer in an invalid state. + The xTaskCreate() and xTaskCreateStatic() functions accept a task priority as an input parameter. The priority has always been silently capped to (configMAX_PRIORITIES - 1) should it be set to a value above that priority. Now values above that priority will also trigger a configASSERT() failure. + Replace configASSERT( pcQueueName ) in vQueueAddToRegistry with a NULL pointer check. + Introduce the configSTACK_ALLOCATION_FROM_SEPARATE_HEAP configuration constant that enables the stack allocated to tasks to come from a heap other than the heap used by other memory allocations. This enables stacks to be placed within special regions, such as fast tightly coupled memory. + If there is an attempt to add the same queue or semaphore handle to the queue registry more than once then prior versions would create two separate entries. Now if this is done the first entry is overwritten rather than duplicated. + Update the ESP32 port and TF-M (Trusted Firmware M)code to the latest from their respective repositories. + Correct a build error in the POSIX port. + Additional minor formatting updates, including replacing tabs with spaces in more files. + Other minor updates include adding additional configASSERT() checks and correcting and improving code comments. + Go look at the smp branch to see the progress towards the Symetric Multiprocessing Kernel. https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/smp Changes between FreeRTOS V10.4.2 and FreeRTOS V10.4.3 released December 14 2020 V10.4.3 is included in the 202012.00 LTS release. Learn more at https:/freertos.org/lts-libraries.html See https://www.FreeRTOS.org/FreeRTOS-V10.4.x.html + Changes to improve robustness and consistency for buffer allocation in the heap, queue and stream buffer. + The following functions can no longer be called from unprivileged code. - xTaskCreateRestricted - xTaskCreateRestrictedStatic - vTaskAllocateMPURegions Changes between FreeRTOS V10.4.1 and FreeRTOS V10.4.2 released November 10 2020 See https://www.FreeRTOS.org/FreeRTOS-V10.4.x.html + Fix an issue in the ARMv8-M ports that caused BASEPRI to be masked between the first task starting to execute and that task making a FreeRTOS API call. + Introduced xTaskDelayUntil(), which is functionally equivalent to vTaskDelayUntil(), with the addition of returning a value to indicating whether or not the function placed the calling task into the Blocked state or not. + Update WolfSSL to 4.5.0 and add the FIPS ready demo. + Add support for ESP IDF 4.2 to ThirdParty Xtensa port. + Re-introduce uxTopUsedPriority to support OpenOCD debugging. + Convert most dependent libraries in FreeRTOS/FreeRTOS to submodules. + Various general maintenance and improvements to MISRA compliance. Changes between FreeRTOS V10.4.0 and FreeRTOS V10.4.1 released September 17 2020 See https://www.FreeRTOS.org/FreeRTOS-V10.4.x.html + Fixed an incorrectly named parameter that prevented the ulTaskNotifyTakeIndexed macro compiling, and the name space clash in the test code that prevented this error causing test failures. Changes between FreeRTOS V10.3.1 and FreeRTOS V10.4.0 released September 10 2020 See https://www.FreeRTOS.org/FreeRTOS-V10.4.x.html Major enhancements: + Task notifications: Prior to FreeRTOS V10.4.0 each created task had a single direct to task notification. From FreeRTOS V10.4.0 each task has an array of notifications. The direct to task notification API has been extended with API functions postfixed with "Indexed" to enable the API to operate on a task notification at any array index. See https://www.freertos.org/RTOS-task-notifications.html for more information. + Kernel ports that support memory protection units (MPUs): The ARMv7-M and ARMv8-M MPU ports now support a privilege access only heap. The ARMv7-M MPU ports now support devices that have 16 MPU regions, have the ability to override default memory attributes for privileged code and data regions, and have the ability to place the FreeRTOS kernel code outside of the Flash memory. The ARMv8-M MPU ports now support tickless idle mode. See https://www.freertos.org/FreeRTOS-MPU-memory-protection-unit.html for more information. Additional noteworthy updates: + Code formatting is now automated to facilitate the increase in collaborative development in Git. The auto-formated code is not identical to the original formatting conventions. Most notably spaces are now used in place of tabs. + The prototypes for callback functions (those that start with "Application", such as vApplicationStackOverflowHook()) are now in the FreeRTOS header files, removing the need for application writers to add prototypes into the C files in which they define the functions. + New Renesas RXv3 port layer. + Updates to the Synopsys ARC code, including support for EM and HS cores, and updated BSP. + Added new POSIX port layer that allows FreeRTOS to run on Linux hosts in the same way the Windows port layer enables FreeRTOS to run on Windows hosts. + Many other minor optimisations and enhancements. For full details see https://github.com/FreeRTOS/FreeRTOS-Kernel/commits/main Changes between FreeRTOS V10.3.0 and FreeRTOS V10.3.1 released February 18 2020 See https://www.FreeRTOS.org/FreeRTOS-V10.3.x.html + ./FreeRTOS-Labs directory was removed from this file. The libraries it contained are now available as a separate download. Changes between FreeRTOS V10.2.1 and FreeRTOS V10.3.0 released February 7 2020 See https://www.FreeRTOS.org/FreeRTOS-V10.3.x.html New and updated kernel ports: + Added RISC-V port for the IAR compiler. + Update the Windows simulator port to use a synchronous object to prevent a user reported error whereby a task continues to run for a short time after being moved to the Blocked state. Note we were not able to replicate the reported issue and it likely depends on your CPU model. + Correct alignment of stack top in RISC-V port when configISR_STACK_SIZE_WORDS is defined to a non zero value, which causes the interrupt stack to be statically allocated. + The RISC-V machine timer compare register can now be for any HART, whereas previously it was always assumed FreeRTOS was running on HART 0. + Update the sequence used to update the 64-bit machine timer compare register on 32-bit cores to match that suggested in RISC-V documentation. + Added tickless low power modes into the ARM, IAR and GCC Cortex-M0 compiler ports. + Updated the behaviour of the ARMv7-M MPU (Memory Protection Unit) ports to match that of the ARMv8-M ports whereby privilege escalations can only originate from within the kernel's own memory segment. Added configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY configuration constant. + Update existing MPU ports to correctly disable the MPU before it is updated. + Added contributed port and demo application for a T-Head (formally C-SKY) microcontroller. New API functions: + Added the vPortGetHeapStats() API function which returns information on the heap_4 and heap_5 state. + Added xTaskCatchUpTicks(), which corrects the tick count value after the application code has held interrupts disabled for an extended period. + Added xTaskNotifyValueClear() API function. + Added uxTimerGetReloadMode() API function. Other miscellaneous changes: + Change type of uxPendedTicks from UBaseType_t to TickType_t to ensure it has the same type as variables with which it is compared to, and therefore also renamed the variable xPendingTicks. + Update Keil projects that use the MPU so memory regions come from linker script (scatter file) variables instead of being hard coded. + Added LPC51U68 Cortex-M0+ demos for GCC (MCUXpresso), Keil and IAR compilers. + Added CORTEX_MPU_STM32L4_Discovery_Keil_STM32Cube demo. + Added LPC54018 MPU demo. + Rename xTaskGetIdleRunTimeCounter() to ulTaskGetIdleRunTimeCounter(). Changes between FreeRTOS V10.2.1 and FreeRTOS V10.2.0 released May 13 2019: + Added ARM Cortex-M23 port layer to complement the pre-existing ARM Cortex-M33 port layer. + The RISC-V port now automatically switches between 32-bit and 64-bit cores. + Introduced the portMEMORY_BARRIER macro to prevent instruction re-ordering when GCC link time optimisation is used. + Introduced the portDONT_DISCARD macro to the ARMv8-M ports to try and prevent the secure side builds from removing symbols required by the non secure side build. + Introduced the portARCH_NAME to provide additional data to select semi- automated build environments. + Cortex-M33 and Cortex-M23 ports now correctly disable the MPU before updating the MPU registers. + Added Nuvoton NuMaker-PFM-M2351 ARM Cortex-M23 demo. + Added LPC55S69 ARM Cortex-M33 demo. + Added an STM32 dual core AMP stress test demo. Changes between FreeRTOS V10.1.1 and FreeRTOS V10.2.0 released February 25 2019: + Added GCC RISC-V MCU port with three separate demo applications. + Included pre-existing ARM Cortex-M33 (ARMv8-M) GCC/ARMclang and IAR ports with Keil simulator demo. + Update the method used to detect if a timer is active. Previously the timer was deemed to be inactive if it was not referenced from a list. However, when a timer is updated it is temporarily removed from, then re-added to a list, so now the timer's active status is stored separately. + Add vTimerSetReloadMode(), xTaskGetIdleRunTimeCounter(), and xTaskGetApplicationTaskTagFromISR() API functions. + Updated third party Xtensa port so it is MIT licensed. + Added configINCLUDE_PLATFORM_H_INSTEAD_OF_IODEFINE_H to the Renesas compiler RX600v2 port to enable switching between platform.h and iodefine.h includes within that port's port.c file. + Removed the 'FromISR' functions from the MPU ports as ISRs run privileged anyway. + Added uxTaskGetStackHighWaterMark2() function to enable the return type to be changed without breaking backward compatibility. uxTaskGetStackHighWaterMark() returns a UBaseType_t as always, uxTaskGetStackHighWaterMark2() returns configSTACK_DEPTH_TYPE to allow the user to determine the return type. + Fixed issues in memory protected ports related to different combinations of static memory only and dynamic memory only builds. As a result the definition of tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE became more complex and was moved to FreeRTOS.h with a table explaining its definition. + Added a 'get task tag from ISR' function. + Change the method used to determine if a timer is active or not from just seeing if it is referenced from the active timer list to storing its active state explicitly. The change prevents the timer reporting that it is inactive while it is being moved from one list to another. + The pcName parameter passed into the task create functions can be NULL, previously a name had to be provided. + When using tickless idle, prvResetNextTaskUnblockTime() is now only called in xTaskRemoveFromEventList() if the scheduler is not suspended. + Introduced portHAS_STACK_OVERFLOW_CHECKING, which should be set to 1 for FreeRTOS ports that run on architectures that have stack limit registers. Changes between FreeRTOS V10.1.0 and FreeRTOS V10.1.1 released 7 September 2018 + Reverted a few structure name changes that broke several kernel aware debugger plug-ins. + Updated to the latest trace recorder code. + Fixed some formatting in the FreeRTOS+TCP TCP/IP stack code. + Reverted moving some variables from file to function scope as doing so broke debug scenarios that require the static qualifier to be removed. Changes between FreeRTOS V10.0.1 and FreeRTOS V10.1.0 released 22 August 2018 FreeRTOS Kernel Changes: + Update lint checked MISRA compliance to use the latest MISRA standard, was previously using the original MISRA standard. + Updated all object handles (TaskHandle_t, QueueHandle_t, etc.) to be unique types instead of void pointers, improving type safety. (this was attempted some years back but had to be backed out due to bugs in some debuggers). Note this required the pvContainer member of a ListItem_t struct to be renamed - set configENABLE_BACKWARD_COMPATIBILITY to 1 if this causes an issue. + Added configUSE_POSIX_ERRNO to enable per task POSIX style errno functionality in a more user friendly way - previously the generic thread local storage feature was used for this purpose. + Added Xtensa port and demo application for the XCC compiler. + Changed the implementation of vPortEndScheduler() for the Win32 port to simply call exit( 0 ). + Bug fix in vPortEnableInterrupt() for the GCC Microblaze port to protect the read modify write access to an internal Microblaze register. + Fix minor niggles when the MPU is used with regards to prototype differences, static struct size differences, etc. + The usStackHighWaterMark member of the TaskStatus_t structure now has type configSTACK_DEPTH_TYPE in place of uint16_t - that change should have been made when the configSTACK_DEPTH_TYPE type (which gets around the previous 16-bit limit on stack size specifications) was introduced. + Added the xMessageBufferNextLengthBytes() API function and likewise stream buffer equivalent. + Introduce configMESSAGE_BUFFER_LENGTH_TYPE to allow the number of bytes used to hold the length of a message in the message buffer to be reduced. configMESSAGE_BUFFER_LENGTH_TYPE default to size_t, but if, for example, messages can never be more than 255 bytes it could be set to uint8_t, saving 3 bytes each time a message is written into the message buffer (assuming sizeof( size_t ) is 4). + Updated the StaticTimer_t structure to ensure it matches the size of the Timer_t structure when the size of TaskFunction_t does not equal the size of void *. + Update various Xilinx demos to use 2018.1 version of the SDK tools. + Various updates to demo tasks to maintain test coverage. + FreeRTOS+UDP was removed in FreeRTOS V10.1.0 as it was replaced by FreeRTOS+TCP, which was brought into the main download in FreeRTOS V10.0.0. FreeRTOS+TCP can be configured as a UDP only stack, and FreeRTOS+UDP does not contain the patches applied to FreeRTOS+TCP. FreeRTOS+TCP Changes: + Multiple security improvements and fixes in packet parsing routines, DNS caching, and TCP sequence number and ID generation. + Disable NBNS and LLMNR by default. + Add TCP hang protection by default. We thank Ori Karliner of Zimperium zLabs Team for reporting these issues. Changes between FreeRTOS V10.0.0 and FreeRTOS V10.0.1, released December 20 2017 + Fix position of "#if defined( __cplusplus )" in stream_buffer.h. + Correct declarations of MPU_xQueuePeek() and MPU_xQueueSemaphoreTake() in mpu_prototypes.h. + Correct formatting in vTaskList() helper function when it prints the state of the currently executing task. + Introduce #error if stream_buffer.c is built without configUSE_TASK_NOTIFICATIONS set to 1. + Update FreeRTOS+TCP to V2.0.0 - Improve the formatting of text that displays the available netword interfaces when FreeRTOS+TCP is used on Windows with WinPCap. - Introduce ipconfigSOCKET_HAS_USER_WAKE_CALLBACK option to enable a user definable callback to execute when data arrives on a socket. Changes between FreeRTOS V9.0.1 and FreeRTOS V10.0.0: The FreeRTOS kernel is now MIT licensed: https://www.FreeRTOS.org/license New Features and components: + Stream Buffers - see https://www.FreeRTOS.org/RTOS-stream-buffer-example.html + Message Buffers - see https://www.FreeRTOS.org//RTOS-message-buffer-example.html + Move FreeRTOS+TCP into the main repository, along with the basic Win32 TCP demo FreeRTOS_Plus_TCP_Minimal_Windows_Simulator. New ports or demos: + Added demo for TI SimpleLink CC3220 MCU. + Added MPU and non MPU projects for Microchip CEC and MEC 17xx and 51xx MCUs. + Added CORTEX_MPU_Static_Simulator_Keil_GCC demo to test static allocation in the MPU port. Fixes or enhancements: + Cortex-M ports push additional register prior to calling vTaskSwitchContext to ensure 8-byte alignment is maintained. Only important if a user defined tick hook function performs an operation that requires 8-byte alignment. + Optimisations to the implementation of the standard tickless idle mode on Cortex-M devices. + Improvements to the Win32 port including using higher priority threads. + Ensure interrupt stack alignment on PIC32 ports. + Updated GCC TriCore port to build with later compiler versions. + Update mpu_wrappers.c to support static allocation. + The uxNumberOfItems member of List_t is now volatile - solving an issue when the IAR compiler was used with maximum optimization. + Introduced configRECORD_STACK_HIGH_ADDRESS. When set to 1 the stack start address is saved into each task's TCB (assuming stack grows down). + Introduced configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H to allow user defined functionality, and user defined initialisation, to be added to FreeRTOS's tasks.c source file. When configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H is set to 1 a user provided header file called freertos_task_c_additions.h will be included at the bottom of tasks.c. Functions defined in that header file can call freertos_tasks_c_additions_init(), which in turn calls a macro called FREERTOS_TASKS_C_ADDITIONS_INIT(), if it is defined. FREERTOS_TASKS_C_ADDITIONS_INIT() can be defined in FreeRTOSConfig.h. + Introduced configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( x ) which can be defined by a user in FreeRTOSConfig.h. The macro is called before assessing whether to enter tickless idle mode or not. If the macro sets x to zero then tickless idle mode will not be entered. This allows users to abort tickless idle mode entry before the tickless idle function is even called - previously it was only possible to abort from within the tickless idle function itself. + Added configPRINTF(), which can be defined by users to allow all libraries to use the same print formatter. + Introduced configMAX() and configMIN() macros which default to standard max( x, y ) and min( x, y ) macro behaviour, but can be overridden if the application writer defines the same macros in FreeRTOSConfig.h. + Corrected the definition of StaticTask_t in the case where INCLUDE_xTaskAbortDelay is set to 1. + Introduced configTIMER_SERVICE_TASK_NAME and configIDLE_TASK_NAME, both of which can be defined to strings in FreeRTOSConfig.h to change the default names of the timer service and idle tasks respectively. + Only fill the stack of a newly created task with a known value if stack checking, or high water mark checking/viewing, is in use - removing the dependency on memset() in other cases. + Introduced xTaskCreateRestrictedStatic() so static allocation can be used with the MPU. + Ensure suspended tasks cannot be unsuspended by a received task notification. + Fix race condition in vTaskSetTimeOutState(). + Updated trace recorder files to the latest version. Changes since FreeRTOS V9.0.0: + Priority dis-inheritance behaviour has been enhanced in the case where a task that attempted to take a mutex that was held by a lower priority task timed out before it was able to obtain the mutex (causing the task that holds the mutex to have its priority raised, then lowered again, in accordance with the priority inheritance protocol). + Split the overloaded xQueueGenericReceive() function into three separate dedicated functions. + Allow the default human readable text names given to the Idle and Timer tasks to be overridden by defining the configIDLE_TASK_NAME and configTIMER_SERVICE_TASK_NAME definitions respectively in FreeRTOSConfig.h. + Introduced configINITIAL_TICK_COUNT to allow the tick count to take a value of than than 0 when the system boots. This can be useful for testing purposes - although setting configUSE_16_BIT_TICKS to 1 can also be used to test frequent tick overflows. + Ensure the Cortex-M SysTick count is cleared to zero before starting the first task. + Add configASSERT() into ARM Cortex-M ports to check the number of priority bit settings. + Clear the 'control' register before starting ARM Cortex-M4F ports in case the FPU is used before the scheduler is started. This just saves a few bytes on the main stack as it prevents space being left for a later save of FPU registers. + Added xSemaphoreGetMutexHolderFromISR(). + Corrected use of portNVIC_PENDSVSET to portNVIC_PENDSVSET_BIT in MPU ports. + Introduced configSTACK_DEPTH_TYPE to allow users to change the type used to specify the stack size when using xTaskCreate(). For historic reasons, when FreeRTOS was only used on small MCUs, the type was set to uint16_t, but that can be too restrictive when FreeRTOS is used on larger processors. configSTACK_DEPTH_TYPE defaults to uint16_t. xTaskCreateStatic(), being a newer function, used a uint32_t. + Increase the priority of the Windows threads used by the Win32 port. As all the threads run on the same core, and the threads run with very high priority, there is a risk that the host will become unresponsive, so also prevent the Windows port executing on single core hosts. Changes between FreeRTOS V9.0.0 and FreeRTOS V9.0.0rc2 released May 25 2016: See https://www.FreeRTOS.org/FreeRTOS-V9.html RTOS kernel updates: + The prototype of the new xTaskCreateStatic() API function was modified to remove a parameter and improve compatibility with other new "CreateStatic()" API functions. The stack size parameter in xTaskCreateStatic() is now uint32_t, which changes the prototype of the callback functions. See the following URL: https://www.FreeRTOS.org/xTaskCreateStatic.html + GCC ARM Cortex-A port: Introduced the configUSE_TASK_FPU_SUPPORT constant. When configUSE_TASK_FPU_SUPPORT is set to 2 every task is automatically given a floating point (FPU) context. + GCC ARM Cortex-A port: It is now possible to automatically save and restore all floating point (FPU) registers on entry to each potentially nested interrupt by defining vApplicationFPUSafeIRQHandler() instead of vApplicationIRQHandler(). + All ARM Cortex-M3/4F/7 ports: Clear the least significant bit of the task entry address placed onto the stack of a task when the task is created for strict compliance with the ARM Cortex-M3/4/7 architecture documentation (no noticeable effect unless using the QMEU emulator). + Added GCC and Keil ARM Cortex-M4F MPU ports - previously the MPU was only supported on ARM Cortex-M3. + ARM Cortex-M3/4F MPU ports: Update to fully support the FreeRTOS V9.0.0 API (other than static object creation) and added the FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC demo application to demonstrate how to use the updated MPU port. + All ARM Cortex-M3/4F/7 ports: Add additional barrier instructions to the default low power tickless implementation. + All ARM Cortex-M0 ports: Prevent an item being left on the stack of the first task that executes. + Win32 ports: Reduce the amount of stack used and change the way Windows threads are deleted to increase the maximum execution time. + Add an ARM Cortex-M4F port for the MikroC compiler. Ensure to read the documentation page for this port before use. + MPS430X IAR port: Update to be compatible with the latest EW430 tools release. + IAR32 GCC port: Correct vPortExitCritical() when configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY. + For consistency vTaskGetTaskInfo() now has the alias vTaskGetInfo(), xTaskGetTaskHandle() now has the alias xTaskGetHandle() and pcQueueGetQueueName() now has an alias pcQueueGetName(). + Fix various errors in comments and compiler warnings. Demo application updates: + Update Atmel Studio projects to use Atmel Studio 7. + Update Xilinx SDK projects to use the 2016.1 version of the SDK. + Remove dependency on legacy IO libraries from the PIC32 demos. + Move the Xilinx UltraScale Cortex-R5 demo into the main distribution. + Update the MSP432 libraries to the latest version. + Add Microchip CEC1302 (ARM Cortex-M4F) demos for GCC, Keil and MikroC compilers. + Move the Atmel SAMA5D2 demo into the main distribution. Changes between FreeRTOS V9.0.0rc1 and FreeRTOS V9.0.0rc2 (release candidate 2) released March 30 2016: NOTE - See https://www.FreeRTOS.org/FreeRTOS-V9.html for details + The functions that create RTOS objects using static memory allocation have been simplified and will not revert to using dynamic allocation if a buffer is passed into a function as NULL. + Introduced the configSUPPORT_DYNAMIC_ALLOCATION configuration constant to allow a FreeRTOS application to be built without a heap even being being defined. The Win32 example located in the /FreeRTOS/demo/WIN32-MSVC-Static-Allocation-Only directory is provided as a reference for projects that do not include a FreeRTOS heap. + Minor run-time optimisations. + Two new low power tickless implementations that target Silicon Labs EFM32 microcontrollers. + Addition of the xTimerGetPeriod() and xTimerGetExpireTime() API functions. Changes between FreeRTOS V8.2.3 and FreeRTOS V9.0.0rc1 (release candidate 1) released February 19 2016: RTOS Kernel Updates: + Major new feature - tasks, semaphores, queues, timers and event groups can now be created using statically allocated memory, so without any calls to pvPortMalloc(). + Major new features - Added the xTaskAbortDelay() API function which allows one task to force another task to immediately leave the Blocked state, even if the event the blocked task is waiting for has not occurred, or the blocked task's timeout has not expired. + Updates necessary to allow FreeRTOS to run on 64-bit architectures. + Added vApplicationDaemonTaskStartupHook() which executes when the RTOS daemon task (which used to be called the timer service task) starts running. This is useful if the application includes initialisation code that would benefit from executing after the scheduler has been started. + Added the xTaskGetTaskHandle() API function, which obtains a task handle from the task's name. xTaskGetTaskHandle() uses multiple string compare operations, so it is recommended that it is called only once per task. The handle returned by xTaskGetTaskHandle() can then be stored locally for later re-use. + Added the pcQueueGetQueueName() API function, which obtains the name of a queue from the queue's handle. + Tickless idling (for low power applications) can now also be used when configUSE_PREEMPTION is 0. + If one task deletes another task, then the stack and TCB of the deleted task is now freed immediately. If a task deletes itself, then the stack and TCB of the deleted task are freed by the Idle task as before. + If a task notification is used to unblock a task from an ISR, but the xHigherPriorityTaskWoken parameter is not used, then pend a context switch that will then occur during the next tick interrupt. + Heap_1.c and Heap_2.c now use the configAPPLICATION_ALLOCATED_HEAP settings, which previously was only used by heap_4.c. configAPPLICATION_ALLOCATED_HEAP allows the application writer to declare the array that will be used as the FreeRTOS heap, and in-so-doing, place the heap at a specific memory location. + TaskStatus_t structures are used to obtain details of a task. TaskStatus_t now includes the bae address of the task's stack. + Added the vTaskGetTaskInfo() API function, which returns a TaskStatus_t structure that contains information about a single task. Previously this information could only be obtained for all the tasks at once, as an array of TaskStatus_t structures. + Added the uxSemaphoreGetCount() API function. + Replicate previous Cortex-M4F and Cortex-M7 optimisations in some Cortex-M3 port layers. Demo Application Updates: Further demo applications will be added prior to the final FreeRTOS V9 release. + Updated SAM4L Atmel Studio project to use Atmel Studio 7. + Added ARM Cortex-A53 64-bit port. + Added a port and demo for the ARM Cortex-A53 64-bit cores on the Xilinx Ultrascale MPSoC. + Added Cortex-M7 SAME70 GCC demo. + Added EFM32 Giant and Wonder Gecko demos. Changes between V8.2.2 and V8.2.3 released October 16, 2015 RTOS kernel updates: + Fix bug identified in a modification made in V8.2.2 to the software timer code that allows tickless low power applications to sleep indefinitely when software timers are used. + Simplify and improve efficiency of stack overflow checking. + Add xTaskNotifyStateClear() API function. + New IAR and GCC Cortex-R ports for microprocessors that do not use an ARM generic interrupt controller (GIC). + New PIC32MEC14xx port. + Add support for PIC32MZ EF parts (with floating point) into the PIC32MZ port. + Zynq7000 port layer now declares the functions that setup and clear the tick interrupt as weak symbols so they can be overridden by the application, and uses a global XScuGic object so the same object can be used by the application code. + Introduced configUSE_TASK_FPU_SUPPORT, although the PIC32MZ EF port is currently the only port that uses it. + Updates to RL78 and 78K0 IAR port layers to improve support for combinations of memory models. + Minor updates to heap_5.c to remove compiler warnings generated by some compilers. + License simplifications. See /FreeRTOS/License/license.txt in the official distribution. FreeRTOS+ updates: + Update directory names to use WolfSSL instead of CyaSSL, inline with WolfSSL's re-branding. + Update to latest WolfSSL code. + Update to latest FreeRTOS+Trace recorder code. + Add in the FreeRTOS+Trace recorder library required for streaming trace. Demo application changes: + Add demo applications for Renesas RZ/T (Cortex-R), PIC32MZ EF (PIC32 with floating point hardware), PIC32MEC14xx, RX71M, RX113 and RX231. + General tidy up of spelling and compiler warnings. Changes between V8.2.1 and V8.2.2 released August 12, 2015 RTOS kernel updates: + Added Intel IA32/x86 32-bit port. + General maintenance. + PRIVILEGED_FUNCTION and PRIVILEGED_DATA macros, which are used in memory protected systems, have been added to the newer event group and software timer functions. + Add the errno definitions used by FreeRTOS+ components into projdefs.h. + Remove the restriction that prevented tick-less idle implementations waiting indefinitely when software timers were used in the same application. + Introduce xTaskNotifyAndQueryFromISR() as the interrupt safe version of xTaskNotifyAndQuery(). + Add additional NOPs to the MSP430X port layers to ensure strict compliance with the hardware documentation. + Microblaze port: Added option for port optimised task selection. + Microblaze port: Previously tasks inherited the exception enable state at the time the task was created. Now all tasks are created with exceptions enabled if the Microblaze design supports exceptions. + Windows port: Add additional safe guards to ensure the correct start up sequence and thread switching timing. + Windows port: Improve the implementation of the port optimised task selection assembly code. + Update heap_4 and heap_5 to allow use on 64-bit processors. + Simplify the code that creates a queue. + General improved tick-less idle behaviour. + Ensure none of the variables in the common kernel files are initialised to anything other than zero. + Correct calculation of xHeapStructSize in heap_4 and heap_5. Demo application updates: + Added demo project for the new IA32/x86 port that targets the Galileo hardware. + Added MSP430FR5969 demos (previously provided as a separate download). + Added FreeRTOS BSP repository for automatic creation of FreeRTOS applications in the Xilinx SDK. + Added Atmel Studio / GCC project for the SAMV71 (ARM Cortex-M7) + Update Xilinx SDK projects to use version 2015.2 of the SDK. + Remove Microblaze demos that were using obsolete tools. + Add MSP43FR5969 IAR and CCS demos. FreeRTOS+ Updates: + Updated FreeRTOS+Trace recorder library, which requires an update to the FreeRTOS+Trace application. + Added Reliance Edge source code and demo application. Reliance edge is a fail safe transactional file system ideal for applications that require file storage, and especially when high reliability is essential. + Introduce configAPPLICATION_PROVIDES_cOutputBuffer to allow FreeRTOS+CLI users to place the output buffer at a fixed memory address. + Improve the NetworkInterface.c file provided for the Windows port of FreeRTOS+UDP. Changes between V8.2.0 and V8.2.1 released 24th March 2015. RTOS kernel updates: + Added user definable and flexible thread local storage facility. + Added vTimerSetTimerID() API function to complement the pvTimerGetTimerID() function to allow the timer's ID to be used as timer local storage. + Fixed a potential issue related to the use of queue sets from an ISR. + Some updates to the Xilinx Microblaze GCC port. + Added ARM Cortex-M4F port for Texas Instruments Code Composer Studio. + Added ARM Cortex-M7 r0p1 port layer for IAR, GCC and Keil which contains a minor errata work around. All other ARM Cortex-M7 core revisions should use the ARM Cortex-M4F port. + Exclude the whole of croutine.c if configUSE_CO_ROUTINES is set to 0. + Change some data types from uint32_t to size_t in preparation for 64-bit Windows port. + Update the PIC32 port to remove deprecation warnings output by the latest XC32 compilers. + Fix bug when xQueueOverwrite() and xQueueOverwrite() from ISR are used to overwrite items in two queues that are part of the same set. Demo application updates: + Added demo application for TI's ARM Cortex-M4F based MSP432 microcontroller using IAR, Keil and CCS compilers. + Added demo application for STM32F ARM Cortex-M7 based microcontroller using IAR and Keil. + Added demo application for Atmel SAMV71 ARM Cortex-M7 based microcontroller using IAR and Keil. + Added Microblaze demo that uses the 2014.4 version of the Xilinx SDK and runs on the KC705 evaluation board (Kintex FPGA). Changes between V8.1.2 and V8.2.0 released 16th January 2015 Changes between release candidate 1 and the official release are restricted to maintenance only. Significant RTOS kernel updates: + MAJOR NEW FEATURE! Task notifications. Please see the following URL for details: https://www.FreeRTOS.org/RTOS-task-notifications.html + NEW HEADER FILE REQUIRED! Obsolete definitions have been separated into a new header file called FreeRTOS/Source/include/deprecated_definitions.h. This header file must be present to build. Note some of the obsolete definitions are still used by very old demo application projects. Other RTOS kernel updates: + Made xSemaphoreGiveFromISR() a function rather than a macro that calls xQueueGenericSendFromISR(). This allows for major performance enhancements at the expense of some additional code size if both functions are used in the same application. NOTE: In most uses cases such use of a semaphore can now be replaced with a task notification which is smaller and faster still. + The TCB is now always allocated such that the task's stack grows away from the TCB (improves debugging of stack overflows as the overflow will not overwrite the task's name). + GCC, IAR and Keil Cortex-M4F ports now use more inlining (performance enhancements at the cost of a little additional code space). + Queues are now allocated with a single call to pvPortMalloc() which allocates both the queue structure and the queue storage area. + Introduced a new critical section macro for reading the tick count that defines away to nothing in cases where the width of the tick allows the tick count to be read atomically (performance benefits - especially when optimisation is on). + Introduced configAPPLICATION_ALLOCATED_HEAP in heap_4.c to allow the application writer to provide their own heap array - and in so doing control the location of the heap. + Introduced configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES which, when set, will include known values in both list and list item structures. The values are intended to assist debugging. If the values get overwritten then it is likely application code has written over RAM used by the kernel. + configASSERT()s in all Cortex-M ports used to test the lowest 5 bits of the interrupt control register to detect taskENTER_CRITICAL() being called from an interrupt. This has been changed to test all 8 bits. + Introduced uxTaskPriorityGetFromISR(). + Microblze V8 port now tests XPAR_MICROBLAZE_0_USE_FPU for inequality to 0 rather than equality to 1, and 2 and 3 are also valid values. + Cortex-A5 GIC-less port no longer passes the address of the interrupting peripheral into the interrupt handler. + Fix an issue in FreeRTOS-MPU where an attempt was made to free the stack belonging to a task when the task was deleted, even when the stack was allocated statically. + Utility (helper) functions that format task statistic information into human readable tables now pad task names with spaces to ensure columns line up correctly even where task name lengths vary greatly. + Update FreeRTOS+Trace recorder library to version 2.7.0. Demo application updates: + Added two new standard demo task sets: IntSemTest and TaskNotify. + Added port and demo application for Atmel SAMA5D4 Cortex-A5 MPU. + Added demo application for Altera Cyclone V Cortex-A9 MPU. + Updated Zynq demo to use version 2014.4 of Xilinx's SDK and added in demo tasks for new RTOS features. + Updated Atmel SAM4E and SAM4S demos to include a lot of additional test and demo tasks. + Fixed a corner case issue in Atmel SAM4L low power tickless implementation, and added button interrupt handling. + Make the interrupt queue tests more tolerant to heave CPU loads. + Updated MSVC FreeRTOS simulator demo to include the latest standard test and demo tasks. + Updated MingW/Eclipse FreeRTOS simulator demo to match the FreeRTOS MSVC simulator demo. + Updated all demos that use FreeRTOS+Trace to work with the latest trace recorder code. Changes between V8.1.1 and V8.1.2 released September 2nd 2014 Move the defaulting of configUSE_PORT_OPTIMISED_TASK_SELECTION into the individual port layers where necessary so it does not affect ports that do not support the definition. Changes between V8.1.0 and V8.1.1 released August 29th 2014 By popular requests - a minor patch to V8.1.0 to re-instate the ability to give a mutex type semaphore (with priority inheritance) from an interrupt handler. Changes between V8.0.1 and V8.1.0 released August 26th 2014 FreeRTOS scheduler, kernel, demo and test updates: + Improved the priority inheritance algorithms to assist integration with off the shelf middleware that may hold multiple mutexes simultaneously. + Introduce heap_5.c, which is similar to heap_4.c but allows the heap to span multiple non-contiguous memory regions. + Updated all Cortex-A9 ports to help trap a couple of common usage errors - the first being when a task incorrectly attempts to exit its implementing function and the second being when a non interrupt safe API function is called from an interrupt. + Update all Cortex-A9 ports to remove obsolete mode switches prior to restoring a task context. + configUSE_PORT_OPTIMISED_TASK_SELECTION now defaults to 1 instead of 0. + Update all Cortex-M3/4F ports to trap a non interrupt safe API function being called from an interrupt handler. + Simplify the alignment checks in heap_4.c. + Update the MSVC Windows simulator demo to use heap_5.c in place of heap_4.c to ensure end users have an example to refer to. + Updated standard demo test code to test the new priority inheritance algorithms. + Updated the standard demo tasks to make use of stdint and the FreeRTOS specific typedefs that were introduced in FreeRTOS V8.0.0. + Introduce the pdMS_TO_TICKS() macro as a more user friendly and intuitive alternative to pdTICKS_PER_MS - both of which can be used to convert a time specified in milliseconds to a time specified in RTOS ticks. + Fix a bug in the Tasking compiler's Cortex-M port that resulted in an incorrect value being written to the basepri register. This only effects users of the Tasking compiler. + Update the Zynq demo to use version 2014.2 of the SDK and add in an lwIP example that demonstrates lwIP being used with both its raw and sockets interfaces. + Updated the CCS Cortex-R4 port to enable it to be built with the latest CCS compiler. New ports and demo applications: + Two Renesas RX64M ports (RXv2 core) and demos introduced, one for the GCC compiler and one for the Renesas compiler. Both demos use e2 studio. + Generic IAR Cortex-A5 port (without any reliance on a GIC) introduced. The new port is demonstrated on an Atmel SAMA5D3 XPlained board. FreeRTOS+ component updates: + Update CyaSSL to the latest version. + Updated the FreeRTOS+ components supplied directly by Real Time Engineers Ltd. to make use of stdint and the FreeRTOS specific typedefs that were introduced in FreeRTOS V8.0.0. + Rework and simplify the FreeRTOS+FAT SL RAM disk driver. Miscellaneous updates and maintenance: + Update the IAR and DS-5/ARM RZ demos to target the official RZ RSK hardware in place of the previously targeted Renesas internal (not publicly available) hardware. + Various other maintenance tasks. Changes between V8.0.0 and V8.0.1 released 2nd May 2014 + Minor fixes to the event group functionality that was released in V8.0.0. The 'clear bits from ISR' functionality is now implemented using a deferred interrupt callback instead of a function, and the 'wait bits' and 'task sync' functions now correctly clear internal control bits before returning a value in every possible path through the respective functions. + Ensure the updating of internal control data is protected by a critical section after a task is deleted or suspended. + Minor fixes to FreeRTOS+FAT SL - namely seeking beyond the end of a file when the offset was not a multiple of the sector size. + Ensure Cortex-A9 system registers are only ever accessed as 32-bit values, even when only the lest significant byte of the register is implemented. Other updates: + Updated the XMC4200 IAR project so it links with version 7.x of the IAR tools. + Add RL78L1C demo. + Add pcTimerGetName() API function. + Call _reclaim_reent() when a task is deleted if configUSE_NEWLIB_REENTRANT is defined. Changes between V7.6.0 and V8.0.0 released 19th Feb 2014 https://www.FreeRTOS.org/upgrading-to-FreeRTOS-V8.html FreeRTOS V8.x.x is a drop-in compatible replacement for FreeRTOS V7.x.x, although a change to the type used to reference character strings may result in application code generating a few (easily clearable) compiler warnings after the upgrade, and an updated typedef naming convention means use of the old typedef names is now discouraged. See https://www.FreeRTOS.org/upgrading-to-FreeRTOS-V8.html for full information. New features and functionality: + Event groups - see https://www.FreeRTOS.org/FreeRTOS-Event-Groups.html + Centralised deferred interrupt processing - see https://www.FreeRTOS.org/xTimerPendFunctionCallFromISR.html Other updates: + Previously, when a task left the Blocked state, a context switch was performed if the priority of the unblocked task was greater than or equal to the priority of the Running task. Now a context switch is only performed if the priority of the unblocked task is greater than the priority of the Running task. + New low power tickless demonstration project that targets the ST STM32L microcontroller - see https://www.FreeRTOS.org/STM32L-discovery-low-power-tickless-RTOS-demo.html + Add xPortGetMinimumEverFreeHeapSize() to heap_4.c. + Small change to the tickless low power implementation on the SAM4L to ensure the alarm value (compare match value) cannot be set to zero when a tickless period is exited due to an interrupt originating from a source other than the RTOS tick. + Update the GCC/Eclipse Win32 simulator demo to make better use of Eclipse resource filters and match the functionality of the MSVC equivalent. + xTaskIsTaskSuspended() is no longer a public function. Use eTaskGetState() in its place. + Improved trace macros, including tracing of heap usage. + Remove one level of indirection when accepting interrupts on the PIC32MZ. + Add Cortex-A9 GCC port layer. + Add Xilinx Zynq demo application. Changes between V7.5.3 and V7.6.0 released 18th November 2013 V7.6.0 changes some behaviour when the co-operative scheduler is used (when configUSE_PREEMPTION is set to 0). It is important to note that the behaviour of the pre-emptive scheduler is unchanged - the following description only applies when configUSE_PREEMPTION is set to 0: WHEN configUSE_PREEMPTION IS SET TO 0 (which is in a small minority of cases) a context switch will now only occur when a task places itself into the Blocked state, or explicitly calls taskYIELD(). This differs from previous versions, where a context switch would also occur when implicitly moving a higher priority task out of the Blocked state. For example, previously, WHEN PREEMPTION WAS TURNED OFF, if task A unblocks task B by writing to a queue, then the scheduler would switch to the higher priority task. Now, WHEN PREEMPTION IS TURNED OFF, if task A unblocks task B by writing to a queue, task B will not start running until task A enters the Blocked state or task A calls taskYIELD(). [If configUSE_PREEMPTION is not set to 0, so the normal pre-emptive scheduler is being used, then task B will start running immediately that it is moved out of the Blocked state]. Other changes: + Added a port layer and a demo project for the new PIC32MZ architecture. + Update the PIC32MX port layer to re-introduce some ehb instructions that were previously removed, add the ability to catch interrupt stack overflows (previously only task stack overflows were trapped), and also add the ability to catch an application task incorrectly attempting to return from its implementing function. + Make dramatic improvements to the performance of the Win32 simulator port layer. + Ensure tasks that are blocked indefinitely report their state as Blocked instead of Suspended. + Slight improvement to the Cortex-M4F port layers where previously one register was inadvertently being saved twice. + Introduce the xSemaphoreCreateBinary() API function to ensure consistency in the semantics of how each semaphore type is created. It is no longer recommended to use vSemaphoreCreateBinary() (the version prefixed with a 'v'), although it will remain in the code for backward compatibility. + Update the Cortex-M0 port layers to allow the scheduler to be started without using the SVC handler. + Added a build configuration to the PIC32MX MPLAB X demo project that targets the PIC32 USB II starter kit. Previously all the build configurations required the Explorer 16 hardware. + Some of the standard demo tasks have been updated to ensure they execute correctly with the updated co-operative scheduling behaviour. + Added comprehensive demo for the Atmel SAM4E, including use of FreeRTOS+UDP, FreeRTOS+FAT SL and FreeRTOS+CLI. FreeRTOS+ Changes: + Minor maintenance on FreeRTOS+UDP. Changes between V7.5.2 and V7.5.3 released October 14 2013 Kernel changes: + Prior to V7.5.x yields requested from the tick hook would occur in the same tick interrupt - revert to that original behaviour. + New API function uxQueueSpacesAvailable(). + Introduced the prvTaskExitError() function to Cortex-M0, Cortex-M3/4 and Cortex-M4F ports. prvTaskExitError() is used to trap tasks that attempt to return from their implementing functions (tasks should call vTaskDelete( NULL ); if they want to exit). + The Cortex-M0 version of portSET_INTERRUPT_MASK_FROM_ISR and portCLEAR_INTERRUPT_MASK_FROM_ISR are now fully nestable. + Improved behaviour and robustness of the default Cortex-M tickless idle behaviour. + Add workaround for silicon errata PMU_CM001 in Infineon XMC4000 devices to all Cortex-M4F ports. + Add Cortex-M0 port for Keil. + Updated Cortus port. + Ensure _impure_ptr is initialised before the scheduler is started. Previously it was not set until the first context switch. FreeRTOS+ changes: + Update FreeRTOS+UDP to V1.0.1 - including direct integration of the FreeRTOS+Nabto task, improvements to the DHCP behaviour, and a correction to the test that prevents the network event hook being called on the first network down event. The FreeRTOS+UDP change history is maintained separately. + Correct the __NVIC_PRIO_BITS setting in the LPC18xx.h header files provided in the NXP CMSIS library, then update the interrupts used by the LPC18xx demos accordingly. + Replace double quotes (") with single quotes (') in FreeRTOS+CLI help strings to ensure the strings can be used with the JSON descriptions used in the FreeRTOS+Nabto demos. Demo and miscellaneous changes: + Added demo for the Atmel SAMD20 Cortex-M0+. The demo includes FreeRTOS+CLI + Added a demo for the Infineon Cortex-M0 that can be built with the IAR Keil and GCC tools. + Updated the Infineon XMC4000 demos for IAR, Keil, GCC and Tasking tools, with additional build configurations to directly support the XMC4200 and XMC4400 devices, in addition to the previously supported XMC4500. + Updated the demo application. + Added additional trace macros traceMALLOC and traceFREE to track heap usage. Changes between V7.5.0 and V7.5.2 released July 24 2013 V7.5.2 makes the new Cortex-M vPortCheckInterruptPriority() function compatible with the STM32 standard peripheral driver library, and adds an extra critical section to the default low power tickless mode implementation. Only users of the STM32 peripheral library or the default tickless implementation need update from version 7.5.0. Changes between V7.4.2 and V7.5.0 released July 19 2013 V7.5.0 is a major upgrade that includes multiple scheduling and efficiency improvements, and some new API functions. Compatibility information for FreeRTOS users: FreeRTOS V7.5.0 is backward compatible with FreeRTOS V7.4.0 with one exception; the vTaskList() and vTaskGetRunTimeStats() functions are now considered legacy, having been replaced by the single uxTaskGetSystemState() function. configUSE_STATS_FORMATTING_FUNCTIONS must be set to 1 in FreeRTOSConfig.h for vTaskList() and vTaskGetRunTimeStats() to be available. Compatibility information for FreeRTOS port writers: vTaskIncrementTick() is now called xTaskIncrementTick() (because it now returns a value). Headline changes: + Multiple scheduling and efficiency improvements. + Core kernel files now pass PC-Lint V8 static checking without outputting any warnings (information on the test conditions will follow). New API functions: + uxTaskGetSystemState() https://www.FreeRTOS.org/uxTaskGetSystemState.html + xQueueOverwrite() https://www.FreeRTOS.org/xQueueOverwrite.html + xQueueOverwriteFromISR() + xQueuePeekFromISR() The following ports and demos, which were previously available separately, are now incorporated into the main FreeRTOS zip file download: + ARM Cortex-A9 IAR + ARM Cortex-A9 ARM compiler + Renesas RZ + Microsemi SmartFusion2 New FreeRTOSConfig.h settings https://freertos.org/a00110.html + configUSE_TIME_SLICING + configUSE_NEWLIB_REENTRANT + configUSE_STATS_FORMATTING_FUNCTIONS + configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS Other changes: + (MPU port only) The configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS options provides a mechanism that allows application writers to execute certain functions in privileged mode even when a task is running in user mode. + Ports that support interrupt nesting now include a configASSERT() that will trigger if an interrupt safe FreeRTOS function is called from an interrupt that has a priority designated as above the maximum system/API call interrupt priority. + The included FreeRTOS+Trace recorder code has been updated to the latest version, and the demo applications that use the trace recorder code have been updated accordingly. + The FreeRTOS Windows Simulator (MSVC version only) has been updated to include a new basic 'blinky' build option in addition to the original comprehensive build option. + Improve RAM usage efficiency of heap_4.c and heap_2.c. + Prevent heap_4.c from attempting to free memory blocks that were not allocated by heap_4.c, or have already been freed. + As FreeRTOS now comes with FreeRTOS+FAT SL (donated by HCC) the Chan FATfs files have been removed from FreeRTOS/Demo/Common. + Fix build error when R4 port is build in co-operative mode. + Multiple port and demo application maintenance activities. Changes between V7.4.1 and V7.4.2 released May 1 2013 NOTE: There are no changes in the FreeRTOS kernel between V7.4.1 and V7.4.2 + Added FreeRTOS+FAT SL source code and demo project. The demo project runs in the FreeRTOS Windows simulator for easy and hardware independent experimentation and evaluation. See https://www.FreeRTOS.org/fat_sl Changes between V7.4.0 and V7.4.1 released April 18 2013 + To ensure strict conformance with the spec and ensure compatibility with future chips data and instruction barrier instructions have been added to the yield macros of Cortex-M and Cortex-R port layers. For efficiency the Cortex-M port layer "yield" and "yield" from ISR are now implemented separately as the barrier instructions are not required in the ISR case. + Added FreeRTOS+UDP into main download. + Reorganised the FreeRTOS+ directory so it now matches the FreeRTOS directory with Source and Demo subdirectories. + Implemented the Berkeley sockets select() function in FreeRTOS+UDP. + Changed (unsigned) casting in calls to standard library functions with (size_t) casting. + Added the Atmel SAM4L and Renesas RX100 demos that demonstrates the tickless (tick suppression) low power FreeRTOS features. + Add a new RL78 IAR demo that targets numerous new RL78 chips and evaluation boards. + Adjusted stack alignment on RX200 ports to ensure an assert was not falsely triggered when configASSERT() is defined. + Updated the Cortex_M4F_Infineon_XMC4500_IAR demo to build with the latest version of EWARM. + Corrected header comments in the het.c and het.h files (RM48/TMS570 demo). Changes between V7.3.0 and V7.4.0 released February 20 2013 + New feature: Queue sets. See: https://www.FreeRTOS.org/Pend-on-multiple-rtos-objects.html + Overhauled the default tickless idle mode implementation provided with the ARM Cortex-M3 port layers. + Enhanced tickless support in the core kernel code with the introduction of the configEXPECTED_IDLE_TIME_BEFORE_SLEEP macro and the eTaskConfirmSleepModeStatus() function. + Added the QueueSet.c common demo/test file. Several demo applications have been updated to use the new demo/test tasks. + Removed reliance on the PLIB libraries from the MPLAB PIC32 port layer and demo applications. + Added the FreeRTOS+Trace recorder code to the MSVC Win32 demo. + Renamed eTaskStateGet() to eTaskGetState() for consistency, and added a pre-processor macro for backward compatibility with the previous name. + Updated functions implemented in the core queue.c source file to allow queue.h to be included from the .c file directly (this prevents compiler warnings that were generated by some compilers). + Updated the CCS Cortex-R4 port layer to replace the CLZ assembler function with the CLZ compiler intrinsic that is provided by the latest versions of the CCS ARM compiler. + Updated all heap_x.c implementations to replace the structure that was used to ensure the start of the heap was aligned with a more portable direct C code implementation. + Added support for PIC24 devices that include EDS. + Minor optimisations to the PIC32 port layer. + Minor changes to tasks.c that allow the state viewer plug-ins to display additional information. + Bug fix: Update prvProcessReceivedCommands() in timers.c to remove an issue that could occur if the priority of the timer daemon task was set below the priority of tasks that used timer services. + Update the FreeRTOS+Trace recorder code to the latest version. Changes between V7.2.0 and V7.3.0 released October 31 2012 + Added ability to override the default scheduler task selection mechanism with implementations that make use of architecture specific instructions. + Added ability to suppress tick interrupts during idle time, and in so doing, provide the ability to make use of architecture specific low power functionality. + Added the portSUPPRESS_TICKS_AND_SLEEP() macro and vTaskStepTick() helper function. + Added the configSYSTICK_CLOCK_HZ configuration constant. + Reworked the Cortex-M3 and Cortex-M4F port layers for GCC, Keil and IAR to directly support basic power saving functionality. + Added hooks to allow basic power saving to be augmented in the application by making use of chip specific functionality. + Minor change to allow mutex type semaphores to be used from interrupts (which would not be a normal usage model for a mutex). + Change the behaviour of the interrupt safe interrupt mask save and restore macros in the Cortex-M ports. The save macro now returns the previous mask value. The restore macro now uses the previous mask value. These changes are not necessary for the kernel's own implementation, and are made purely because the macros were being used by application writers. + Added eTaskStateGet() API function. + Added port specific optimisations to the PIC32 port layer, and updated the PIC32 demo applications to make use of this new feature. + Added port specific optimisations to the Win32 simulator port. + Added new ports and demo applications for the TI Hercules RM48 and TMS570 safety microcontrollers. + Added SAM3 demos targeting the ATSAM3S-EK2 and ATSAM3X-EK evaluation boards. + Updated the PIC32 MPLAB X project to manually set the compiler include paths instead of using the IDE entry box following reports that the include paths were somehow being deleted. + Improved character handling in FreeRTOS+CLI. Changes between V7.1.1 and V7.2.0 released 14 August 2012 FreeRTOS V7.2.0 is backward compatible with FreeRTOS V7.1.2. + Added a FreeRTOS+ sub-directory. The directory contains some FreeRTOS+ source code, and example projects that use the FreeRTOS Win32 simulator. + Added a new example heap allocation implementation (heap_4.c) that includes memory block coalescence. + Added a demo that targets the Atmel SAM4S Cortex-M4 based microcontroller. The demo is preconfigured to build using the free Atmel Studio 6 IDE and GCC compiler. + Added xSemaphoreTakeFromISR() implementation. + The last parameter in ISR safe FreeRTOS queue and semaphore functions (xHigherPriorityTaskWoken) is now optional and can be set to NULL if it is not required. + Update the IAR and MSP430X ports to clear all lower power mode bits before exiting the tick interrupt [bug fix]. + Allow xQueueReset() to be used, even when the queues event lists are not empty. + Added a vQueueDelete() handler for the FreeRTOS MPU port (this was previously missing). + Updated the vPortSVCHandler() functions in the FreeRTOS MPU port layer to ensure it compiles with the latest ARM GCC compilers from Linaro. + Updated the prvReadGP() function in the NIOS II port to ensure the compiler can choose any register for the functions parameter (required at high compiler optimisation levels). + Add #error macros into the Keil and IAR Cortex-M ports to ensure they cannot be built if the user has set configMAX_SYSCALL_INTERRUPT_PRIORITY to 0. + Added comments in the FreeRTOSConfig.h files associated with Cortex-M3 and Cortex-M4 demos stating that the configMAX_SYSCALL_INTERRUPT_PRIORITY parameter must not be set to 0. + Introduce new INCLUDE_xQueueGetMutexHolder configuration constant (defaulted to 0). + Added two new list handling macros - for internal use only in upcoming new products. + Removed all mention of the legacy vTaskStartTrace and ulTaskEndTrace macros. FreeRTOS+Trace supersedes the legacy trace. + Added a configASSERT() into the vPortFree() function in heap_1.c as it is invalid for the function to be called. + Made the xRxLock and xTxLock members of the queue structure volatile. This is probably not necessary, and is included as a precautionary measure. + Modify the assert() that checks to see if the priority passed into an xTaskCreate() function is within valid bounds to permit the assert to be used in the FreeRTOS MPU port. + The software timer service (daemon) task is now created in a way that to ensure compatibility with FreeRTOS MPU. Changes between V7.1.0 and V7.1.1 released May 1 2012 New ports: The following ports are brand new: + Cortex-M3 Tasking The following ports have been available as separate downloads for a number of months, but are now included in the main FreeRTOS download. + Cortex-M0 IAR + Cortex-M0 GCC + Cortex-M4F GCC (with full floating point support) New demos: The following demos are brand new: + Renesas RX63N RDK (Renesas compiler) The following demos have been available as separate downloads for a number of months, but are now included in the main FreeRTOS download. + NXP LPC1114 GCC/LPCXpresso + ST STM32F0518 IAR + Infineon XMC4500 GCC/Atollic + Infineon XMC4500 IAR + Infineon XMC4500 Keil + Infineon XMC4500 Tasking Kernel miscellaneous / maintenance: + Introduced the portSETUP_TCB() macro to remove the requirement for the Windows simulator to use the traceTASK_CREATE() macro, leaving the trace macro available for use by FreeRTOS+Trace (https://www.FreeRTOS.org/trace). + Added a new trace macro, traceMOVE_TASK_TO_READY_STATE(), to allow future FreeRTOS+Trace versions to provide even more information to users. + Updated the FreeRTOS MPU port to be correct for changes that were introduced in FreeRTOS V7.1.0. + Introduced the xQueueReset() API function. + Introduced the xSemaphoreGetMutexHolder() API function. + Tidy up various port implementations to add the static key word where appropriate, and remove obsolete code. + Slight change to the initial stack frame given to the RX600 ports to allow them to be used in the Eclipse based E2Studio IDE without confusing GDB. + Correct the alignment given to the initial stack of Cortex-M4F tasks. + Added a NOP following each DINT instruction on MSP430 devices for strict conformance with the instructions on using DINT. + Changed the implementation of thread deletes in the Win32 port to prevent the port making use of the traceTASK_DELETE() trace macros - leaving this macro free for use by FreeRTOS+Trace. + Made some benign changes to the RX600 Renesas compiler port layer to ensure the code can be built to a library without essential code being removed by the linker. + Reverted the change in the name of the uxTaskNumber variable made in V7.1.0 as it broke the IAR plug-in. Demo miscellaneous / maintenance: + The command interpreter has now been formally released as FreeRTOS+CLI, and been moved out of the main FreeRTOS download, to instead be available from the FreeRTOS+ Ecosystem site https://www.FreeRTOS.org/plus. + flash_timer.c/h has been added to the list of standard demo tasks. This performs the same functionality as the flash.c tasks, but using software timers in place of tasks. + Upgraded the PIC32 demo as follows: Changes to how the library functions are called necessitated by the new compiler version, addition of MPLAB X project with PIC32MX360, PIC32MX460 and PIC32MX795 configurations, addition of simply blinky demo, updated FreeRTOSConfig.h to include more parameters, addition of hook function stubs. + The MSP430X IAR and CCS demos have been updated to ensure the power settings are correct for the configured CPU frequency. + Rowley CrossWorks projects have been updated to correct the "multiple definition of ..." warnings introduced when the toolchain was updated. + Updated various FreeRTOSConfig.h header files associated with projects that build with Eclipse to include a #error statement informing the user that the CreateProjectDirectoryStructure.bat batch file needs to be executed before the projects can be opened. + Renamed directories that included "CCS4" in their name to remove the '4' and instead just be "CCS". This is because the demo was updated and tested to also work with later Code Composer Studio versions. + Updated the TCP/IP periodic timer frequency in numerous uIP demos to be 50ms instead of 500ms. Changes between V7.0.2 and V7.1.0 released December 13 2011 New ports: + Cortex-M4F IAR port. + Cortex-M4F Keil/RVDS port. + TriCore GCC port. New demos: + NXP LPC4350 using the Keil MDK, and demonstrated on a Hitex development board. + ST STM32F407 using the IAR Embedded Workbench for ARM, and demonstrated on the IAR STM32F407ZG-SK starter kit. + Infineon TriCore TC1782, using the GCC compiler, demonstrated on the TriBoard TC1782 evaluation board. + Renesas RX630, using the Renesas compiler and HEW, demonstrated on an RX630 RSK (Renesas Starter Kit). Miscellaneous / maintenance: + Removed all calls to printf() from the K60/IAR Kinetis demo so the project can execute stand alone - without being connected to the debugger. + Completed the command interpreter framework. Command handlers now receive the entire command string, giving them direct access to parameters. Utility functions are provided to check the number of parameters, and return parameter sub-strings. + The previously documented fix for the bug in xTaskResumeFromISR() that effected (only) ports supporting interrupt nesting has now been incorporated into the main release. + The portALIGNMENT_ASSERT_pxCurrentTCB() definition has been added to allow specific ports to skip the second stack alignment check when a task is created. This is because the second check is not appropriate for some ports - including the new TriCore port where the checked pointer does not actually point to a stack. + The portCLEAN_UP_TCB() macro has been added to allow port specific clean up when a task is deleted - again this is required by the TriCore port. + Various other minor changes to ensure warning free builds on a growing number of microcontroller and toolchain platforms. This includes a (benign) correction to the prototype of the vApplicationStackOverflowHook() definition found in lots of recent demos. Trace system: + The legacy trace mechanism has been completely removed - it has been obsolete for the years since the trace macros were introduced. The configuration constant configUSE_TRACE_FACILITY is now used to optionally include additional queue and task information. The additional information is intended to make the trace mechanism more generic, and allow the trace output to provide more information. When configUSE_TRACE_FACILITY is set to 1: - the queue structure includes an additional member to hold the queue type, which can be base, mutex, counting semaphore, binary semaphore or recursive mutex. - the queue structure includes an additional member to hold a queue number. A trace tool can set and query the queue number for its own purposes. The kernel does not use the queue number itself. - the TCB structure includes an additional member to hold a task number number. A trace tool can set and query the task number for its own purposes. The kernel does not use the task number itself. + Queues and all types of semaphores are now automatically allocated their type as they are created. + Added two new trace macros - traceTASK_PRIORITY_INHERIT() and traskTASK_PRIORITY_DISINHERIT(). + Updated the traceQUEUE_CREATE_FAILED() macro to take a parameter that indicates the type of queue, mutex, or semaphore that failed to be created. + The position from which traceCREATE_MUTEX() is called has been moved from after the call to xQueueGenericSend() [within the same function] to before the call. This ensures the trace events occur in the correct order. + The value passed into tracePRIORITY_SET() has been corrected for the case where vTaskPrioritySet() is called with a null parameter. Changes between V7.0.1 and V7.0.2 released September 20 2011 New ports: + The official FreeRTOS Renesas RX200 port and demo application have been incorporated into the main FreeRTOS zip file download. + The official FreeRTOS Renesas RL78 port and demo application have been incorporated into the main FreeRTOS zip file download. + The official FreeRTOS Freescale Kinetis K60 tower demo application has been incorporated into the main FreeRTOS zip file download. This includes an embedded web server example. + A new Microblaze V8 port layer has been created to replace the older, now deprecated, port layer. The V8 port supports V8.x of the Microblaze IP, including exceptions, caches, and the floating point unit. A new Microblaze demo has also been added to demonstrate the new Microblaze V8 port layer. The demo application was created using V13.1 of the Xilinx EDK, and includes a basic embedded web server that uses lwIP V1.4.0. + The official FreeRTOS Fujitsu FM3 MB9A310 demo application has been incorporated into the main FreeRTOS zip file download. Projects are provided for both the IAR and Keil toolchains. API additions: + xTaskGetIdleTaskHandle() has been added. + xTaskGetTimerDaemonTaskHandle() has been added. + pcTaskGetTaskName() has been added. + vSemaphoreDelete() macro has been added to make it obvious how to delete a semaphore. In previous versions vQueueDelete() had to be used. + vTaskCleanUpResources() has been removed. It has been obsolete for a while. + portPOINTER_SIZE_TYPE has been introduced to prevent compiler warnings being generated when the size of a pointer does not match the size of the stack type. This will (has already) be used in new ports, but will not be retrofitted to existing ports until the existing port itself is updated. Other updates and news: + The core files have all been modified to tighten the coding standard even further. These are style, not functional changes. + All ARM7 port layers have been slightly modified to prevent erroneous assert() failures when tasks are created and configASSERT() is defined. + All ARM IAR projects have been updated to build with the latest V6.2.x versions of the IAR Embedded Workbench for ARM tools (EWARM). This was necessary due to a change in the way EWARM uses the CMSIS libraries. + The PIC32 port layer has been updated in preparation for V2 of the C32 compiler. + The old Virtex-4 Microblaze demo has been marked as deprecated. Please use the brand new Spartan-6 port and demo in its place. + The bones of a new generic command interpreter is located in FreeRTOS/Demo/Common/Utils/CommandInterpreter.c. This is still a work in progress, and not documented. It is however already in use. It will be documented in full when the projects that are already using it are completed. + A couple of new standard demos have been included. First, a version of flop.c called sp_flop.c. This is similar to flop.c, but uses single precision floats in place of double precision doubles. This allows the for testing ports to processors that have only single precision floating point units, and revert to using emulated calculations whenever a double is used. Second, comtest_strings.c has been included to allow the test of UART drivers when an entire string is transmitted at once. The previous comtest.c only used single character transmission and reception. + lwIP V1.4.0 is now included in the FreeRTOS/Demo/Common directory, and used by a couple of new demos. Changes between V7.0.0 and V7.0.1 released May 13 2011 + Added a Fujitsu FM3 demo application for both the IAR and Keil tool chains. + Added a SmartFusion demo application for all of the IAR, Keil and SoftConsole (GCC/Eclipse) tool chains. + Updated the RX600 port and demo applications to take into account the different semantics required when using the latest (V1.0.2.0) version of the Renesas compiler. + Modified the RX600 Ethernet driver slightly to make it more robust under heavy load, and updated the uIP handling task to make use of the FreeRTOS software timers. + Slightly changed the PIC32 port layer to move an ehb instruction in line with the recommendations of the MIPS core manual, and ensure 8 byte stack alignment is truly always obtained. + Changed the behaviour when tasks are suspended before the scheduler has been started. Before, there needed to be at least one task that was not in the suspended state. This is no longer the case. Changes between V6.1.1 and V7.0.0 released April 8 2011 FreeRTOS V7.0.0 is backward compatible with FreeRTOS V6.x.x Main changes: + Introduced a new software timer implementation. + Introduced a new common demo application file to exercise the new timer implementation. + Updated the Win32/MSVC simulator project to include the new software timer demo tasks and software timer tick hook test. Much simpler software timer demonstrations are included in the demo projects for both of the new ports (MSP430X with CCS4 and STM32 with TrueStudio). + Various enhancements to the kernel implementation in tasks.c. These are transparent to users and do not effect the pre-existing API. + Added calls to configASSERT() within the kernel code. configASSERT() is functionally equivalent to the standard C assert() macro, but does not rely on the compiler providing assert.h. Other changes: + Updated the MSP430X IAR port and demo project to include support for the medium memory model. + Added a demo project for the MSP430X that targets the MSP430X Discovery board and uses the Code Composer Studio 4 tools. This demo includes use of the new software timer implementation. + Added an STM32F100RB demo project that targets the STM32 Discovery Board and uses the TrueStudio Eclipse based IDE from Atollic. + Removed some compiler warnings from the PSoC demo application. + Updated the PIC32 port layer to ensure the configMAX_SYSCALL_INTERRUPT_PRIORITY constant works as expected no matter what its value is (within the valid range set by the microcontroller kernel). + Updated the PIC24, dsPIC and PIC32 projects so they work with the latest MPLAB compiler versions from Microchip. + Various cosmetic changes to prepare for a standards compliance statement that will be published after the software release. Changes between V6.1.0 and V6.1.1 released January 14 2011 + Added two new Windows simulator ports. One uses the free Microsoft Visual Studio 2010 express edition, and the other the free MingW/Eclipse environment. Demo projects are provided for both. + Added three demo projects for the PSoC 5 (CYAC5588). These are for the GCC, Keil, and RVDS build tools, and all use the PSoC Creator IDE. + Added a demo for the low power STM32L152 microcontroller using the IAR Embedded Workbench. + Added a new port for the MSP430X core using the IAR Embedded Workbench. + Updated all the RX62N demo projects that target the Renesas Demonstration Kit (RDK) to take into account the revered LED wiring on later hardware revisions, and the new J-Link debug interface DLL. + Updated all the RX62N demo projects so the IO page served by the example embedded web server works with all web browsers. + Updated the Red Suite projects to work with the up coming Red Suite release, and to use a more recent version of the CMSIS libraries. + Added the traceTAKE_MUTEX_RECURSIVE_FAILED() trace macro. + Removed the (pointless) parameter from the traceTASK_CREATE_FAILED() trace macro. + Introduced the portALT_GET_RUN_TIME_COUNTER_VALUE() macro to compliment the already existing portGET_RUN_TIME_COUNTER_VALUE(). This allows for more flexibility in how the time base for the run time statistics feature can be implemented. + Added a "cpsie i" instruction before the "svc 0" instruction used to start the scheduler in each of the Cortex M3 ports. This is to ensure that interrupts are globally enabled prior to the "svc 0" instruction being executed in cases where interrupts are left disabled by the C start up code. + Slight optimisation in the run time stats calculation. Changes between V6.0.5 and V6.1.0 released October 6 2010 + Added xTaskGetTickCountFromISR() function. + Modified vTaskSuspend() to allow tasks that have just been created to be immediately suspended even when the kernel has not been started. This allows them to effectively start in the Suspended state - a feature that has been asked for on numerous occasions to assist with initialisation procedures. + Added ports for the Renesas RX62N using IAR, GCC and Renesas tool suites. + Added a STM32F103 demo application that uses the Rowley tools. + Under specific conditions xFreeBytesRemaining within heap_2.c could end up with an incorrect value. This has been fixed. + xTaskCreateGeneric() has a parameter that can be used to pass the handle of the task just created out to the calling task. The assignment to this parameter has been moved to ensure it is assigned prior to the newly created having any possibility of executing. This takes into account the case where the assignment is made to a global variable that is accessed by the newly created task. + Fixed some build time compiler warnings in various FreeTCPIP (based on uIP) files. + Fixed some build time compiler warnings in Demo/Common/Minimal/IntQueue.c. Changes between V6.0.4 and V6.0.5 released May 17 2010 + Added port and demo application for the Cortus APS3 processor. Changes between V6.0.3 and V6.0.4 released March 14 2010 + All the contributed files that were located in the Demo/Unsupported_Demos directory have been removed. These files are instead now available in the new Community Contributions section of the FreeRTOS website. See https://www.FreeRTOS.org/RTOS-contributed-ports.html + The project file located in the Demo/CORTEX_STM32F107_GCC_Rowley directory has been upgraded to use V2.x of the Rowley Crossworks STM32 support package. + An initial Energy Micro EFM32 demo has been included. This will be updated over the coming months to make better use of the low power modes the EFM32 provides. Changes between V6.0.2 and V6.0.3 released February 26 2010 + SuperH SH7216 (SH2A-FPU) port and demo application added. + Slight modification made to the default implementation of pvPortMallocAligned() and vPortFreeAligned() macros so by default they just call pvPortMalloc() and vPortFree(). The macros are only needed to be defined when a memory protection unit (MPU) is being used - and then only depending on other configuration settings. Changes between V6.0.1 and V6.0.2 released January 9th 2010 + Changed all GCC ARM 7 ports to use 0 as the SWI instruction parameter. Previously the parameter was blank and therefore only an implicit 0 but newer GCC releases do not permit this. + Updated IAR SAM7S and SAM7X ports to work with IAR V5.40. + Changed the stack alignment requirement for PIC32 from 4 bytes to 8 bytes. + Updated prvListTaskWithinSingleList() is it works on processors where the stack grows up from low memory. + Corrected some comments. + Updated the startup file for the RVDS LPC21xx demo. Changes between V6.0.0 and V6.0.1 released November 15th 2009 + Altered pxPortInitialiseStack() for all Cortex-M3 ports to ensure the stack pointer is where the compiler expects it to be when a task first starts executing. The following minor changes only effect the Cortex-M3 MPU port: + portRESET_PRIVILEGE() assembly macro updated to include a clobber list. + Added prototypes for all the privileged function wrappers to ensure no compile time warnings are generated no matter what the warning level setting. + Corrected the name of portSVC_prvRaisePrivilege to portSVC_RAISE_PRIVILEGE. + Added conditional compilation into xTaskGenericCreate() to prevent some compilers issuing warnings when portPRIVILEGE_BIT is defined as zero. Changes between V5.4.2 and V6.0.0 released October 16th 2009 FreeRTOS V6 is backward compatible with FreeRTOS V5.x. Main changes: + FreeRTOS V6 is the first version to include memory protection unit (MPU) support. Two ports now exist for the Cortex M3, the standard FreeRTOS which does not include MPU support, and FreeRTOS-MPU which does. + xTaskCreateRestricted() and vTaskAllocateMPURegions() API functions added in support of FreeRTOS-MPU. + Wording for the GPL exception has been (hopefully) clarified. Also the license.txt file included in the download has been fixed (the previous version contained some corruption). Other changes: + New API function xPortGetFreeHeapSize() added to heap_1.c and heap_2.c. + ARM7 GCC demo interrupt service routines wrappers have been modified to call the C portion using an __asm statement. This prevents the function call being inlined at higher optimisation levels. + ARM7 ports now automatically set the THUMB bit if necessary when setting up the initial stack of a task - removing the need for THUMB_INTERWORK to be defined. This also allows THUMB mode and ARM mode tasks to be mixed more easily. + All ARM7/9 ports now have portBYTE_ALIGNMENT set to 8 by default. + Various demo application project files have been updated to be up to date with the latest IDE versions. + The linker scripts used with command line GCC demos have been updated to include an eh_frame section to allow their use with the latest Yagarto release. Likewise the demo makefiles have been updated to include command line options to reduce or eliminate the eh_frame section all together. + The definition of portBYTE_ALIGNMENT_MASK has been moved out of the various memory allocation files and into the common portable.h header file. + Removed unnecessary use of portLONG, portSHORT and portCHAR. + Added LM3Sxxxx demo for Rowley CrossWorks. + Posix simulator has been upgraded - see the corresponding WEB page on the FreeRTOS.org site. Changes between V5.4.1 and V5.4.2 released August 9th 2009 + Added a new port and demo app for the Altera Nios2 soft core. + Added LPC1768 demo for IAR. + Added a USB CDC demo to all LPC1768 demos (Code Red, CrossWorks and IAR). + Changed clock frequency of LPC1768 demos to 99MHz. Changes between V5.4.0 and V5.4.1 released July 25th 2009 + New hook function added. vApplicationMallocFailedHook() is (optionally) called if pvPortMalloc() returns NULL. + Additional casting added to xTaskCheckForTimeOut(). This prevents problems that can arise should configUSE_16_BIT_TICKS be set to 1 on a 32 bit architecture (which would probably be a mistake, anyway). + Corrected the parameter passed to NVIC_SetPriority() to set the MAC interrupt priority in both LPC1768 demos. + Decreased the default setting of configMINIMAL_STACK_SIZE in the PIC32 demo application to ensure the heap space was not completely consumed before the scheduler was started. Changes between V5.3.1 and V5.4.0 released July 13th 2009 + Added Virtex5 / PPC440 port and demos. + Replaced the LPC1766 Red Suite demo with an LPC1768 Red Suite demo. The original demo was configured to use engineering samples of the CPU. The new demo has an improved Ethernet driver. + Added LPC1768 Rowley demo with zero copy Ethernet driver. + Reworked byte alignment code to ensure 8 byte alignment works correctly. + Set configUSE_16_BIT_TICKS to 0 in the PPC405 demo projects. + Changed the initial stack setup for the PPC405 to ensure the small data area pointers are setup correctly. Changes between V5.3.0 and V5.3.1 released June 21st 2009 + Added ColdFire V1 MCF51CN128 port and WEB server demo. + Added STM32 Connectivity Line STM32107 Cortex M3 WEB server demo. + Changed the Cortex M3 port.c asm statements to __asm so it can be compiled using Rowley CrossWorks V2 in its default configuration. + Updated the Posix/Linux simulator contributed port. Changes between V5.2.0 and V5.3.0 released June 1st 2009 Main changes: + Added new (optional) feature that gathers statistics on the amount of CPU time used by each task. + Added a new demo application for the Atmel AT91SAM3U Cortex-M3 based microcontroller. + Added a new demo application for the NXP LPC1766 Cortex-M3 based microcontroller. + Added a contributed port/demo that allows FreeRTOS to be 'simulated' in a Linux environment. Minor changes: + Updated the Stellaris uIP WEB server demos to include the new run time statistics gathering feature - and include a served WEB page that presents the information in a tabular format. + Added in the lwIP port layer for the Coldfire MCF52259. + Updated the CrossWorks LPC2368 WEB server to include an image in the served content. + Changed some of the timing in the initialisation of the LPC2368 MAC to permit its use on all part revisions. + Minor modifications to the core uIP code to remove some compiler warnings. + Added xTaskGetApplicationTaskTag() function and updated the OpenWatcom demo to make use of the new function. + Added contributed demos for AVR32 AP7000, STM32 Primer 2 and STM32 using Rowley Crossworks. + Heap_1.c and Heap_2.c used to define structures for the purpose of data alignment. These have been converted to unions to save a few bytes of RAM that would otherwise be wasted. + Remove the call to strncpy() used to copy the task name into the TCB when the maximum task name is configured to be 1 byte long. Changes between V5.1.2 and V5.2.0 released March 14th 2009 + Optimised the queue send and receive functions (also used by semaphores). + Replaced the standard critical sections used to protect BIOS calls in the PC port to instead use scheduler locks. This is because the BIOS calls always return with interrupts enabled. + Corrected unclosed comments in boot.s. Changes between V5.1.1 and V5.1.2 released February 9th 2009 + Added NEC V850ES port and demo. + Added NEC 78K0R port and demo. + Added MCF52259 port and demo. + Added the AT91SAM9XE port and demo. + Updated the MCF52233 FEC driver to work around a silicon bug that prevents the part auto negotiating some network parameters. + Minor modifications to the MCF52233 makefile to permit it to be used on Linux hosts. + Updated the STM32 primer files to allow them to be built with the latest version of the RIDE tools. + Updated the threads.js Java script used for kernel aware debugging in the Rowley CrossWorks IDE. Changes between V5.1.0 and V5.1.1 released November 20, 2008 + Added Coldfire MCF52233 WEB server demo using GCC and Eclipse. + Added IAR MSP430 port and demo. + Corrected several compiler time issues that had crept in as tool versions change. + Included FreeRTOS-uIP - a faster uIP. This is not yet complete. Changes between V5.0.4 and V5.1.0 released October 24, 2008 + Added a new port and demo application for the ColdFire V2 core using the CodeWarrior development tools. + Replaced the ARM7 demo that used the old (and now no longer supported) Keil compiler with a new port that uses the new Keil/RVDS combo. + Stack overflow checking now works for stacks that grow up from low memory (PIC24 and dsPIC). + BUG FIX - set the PIC32 definition of portSTACK_GROWTH to the correct value of -1. + MSP430 port layers have been updated to permit tasks to place the microcontroller into power down modes 1 to 3. The demo applications have likewise been updated to demonstrate the new feature. + Replaced the two separate MSP430/Rowley port layers with a single and more flexible version. + Added more contributed ports, including ports for NEC and SAM9 microcontrollers. + Changed the linker script used in the LPC2368 Eclipse demo. Changes between V5.0.3 and V5.0.4 released September 22, 2008 + Completely re-written port for ColdFire GCC. + Bug fix: All Cortex M3 ports have a minor change to the code that sets the pending interrupt. + Some header files require that FreeRTOS.h be included prior to their inclusion. #error message have been added to all such header file informing users to the cause of the compilation error should the headers not be included in the correct order. Changes between V5.0.2 and V5.0.3 released July 31, 2008 Changes relating to the Cortex M3: + Added configMAX_SYSCALL_INTERRUPT_PRIORITY usage to all the Cortex M3 ports and demos. See the port documentation pages on the FreeRTOS.org WEB site for full usage information. + Improved efficiency of Cortex M3 port even further. + Ensure the Cortex M3 port works no matter where the vector table is located. + Added the IntQTimer demo/test tasks to a demo project for each CM3 port (Keil, GCC and IAR) to test the new configMAX_SYSCALL_INTERRUPT_PRIORITY functionality. + Added the mainINCLUDE_WEB_SERVER definition to the LM3SXXXX IAR and Keil projects to allow the WEB server to be conditionally excluded from the build and therefore allow use of the KickStart (code size limited) compiler version. Other changes: + Moved the PIC24 and dsPIC versions of vPortYield() from the C file to an assembly file to allow use with all MPLAB compiler versions. This also allows the omit-frame-pointer optimisation to be turned off. Changes between V5.0.0 and V5.0.2 released May 30, 2008 + Updated the PIC32 port to allow queue API calls to be used from interrupts above the kernel interrupt priority, and to allow full interrupt nesting. Task stack usages has also been reduced. + Added a new PowerPC port that demonstrates how the trace macros can be used to allow the use of a floating point co-processor. The traceTASK_SWITCHED_OUT() and traceTASK_SWITCHED_INT() macros are used to save and restore the floating point context respectively for those tasks that actually use floating point operations. + BUG FIX: The first PPC405 port contained a bug in that it did not leave adequate space above the stack for the backchain to be saved when a task started to execute for the first time. + Updated queue.c to add in the means to allow interrupt nesting and for queue API functions to be called from interrupts that have a priority above the kernel priority. This is only supported on PIC32 ports thus far. + Fixed the compiler warnings that were generated when the latest version of WinAVR was used. + Remove all inline usage of 'inline' from the core kernel code. + Added the queue registry feature. The queue registry is provided as a means for kernel aware debuggers to locate queue definitions. It has no purpose unless you are using a kernel aware debugger. The queue registry will only be used when configQUEUE_REGISTRY_SIZE is greater than zero. + Added the ST Cortex-M3 drivers into the Demo/Common/Drivers directory to prevent them from having to be included in multiple demos. + Added a Keil STM32 demo application. + Changed the blocktim.c test files as it is no longer legitimate for all ports to call queue API functions from within a critical section. + Added the IntQueue.c test file to test the calling of queue API functions from different interrupt priority levels, and test interrupt nesting. Changes between V5.0.0 and V5.0.1 + V5.0.1 was a customer specific release. Changes between V4.8.0 and V5.0.0 released April 15, 2008 *** VERY IMPORTANT INFORMATION ON UPGRADING TO FREERTOS.ORG V5.0.0 *** The parameters to the functions xQueueSendFromISR(), xQueueSendToFrontFromISR(), xQueueSendToBackFromISR() and xSemaphoreGiveFromISR() have changed. You must update all calls to these functions to use the new calling convention! Your compiler might not issue any type mismatch warnings! Other changes: + Support added for the new Luminary Micro LM3S3768 and LM3S3748 Cortex-M3 microcontrollers. + New task hook feature added. + PowerPC demo updated to use version 10.1 of the Xilinx EDK. + Efficiency gains within the PIC32 port layer. Changes between V4.7.2 and V4.8.0 released March 26 2008 + Added a Virtex4 PowerPC 405 port and demo application. + Added optional stack overflow checking and new uxTaskGetStackHighWaterMark() function. + Added new xQueueIsQueueEmptyFromISR(), xQueueIsQueueFullFromISR() and uxQueueMessagesWaitingFromISR() API functions. + Efficiency improvements to the Cortex-M3 port layer. NOTE: This requires that an SVC handler be installed in the application. + Efficiency improvements to the queue send and receive functions. + Added new trace macros. These are application definable to provide a flexible trace facility. + Implemented the configKERNEL_INTERRUPT_PRIORITY within the Keil Cortex M3 port layer (bringing it up to the same standard as the IAR and GCC versions). + Ports that used the arm-stellaris-eabi-gcc tools have been converted to use the arm-non-eabi-gcc tools. Changes between V4.7.1 and V4.7.2 released February 21, 2008 + Added Fujitsu MB91460 port and demo. + Added Fujitsu MB96340 port and demo. + Tidied up the capitalisation of include files to facilitate builds on Linux hosts. + Removed some redundant casting that was generating warnings - but was included to remove warnings on other compilers. Changes between V4.7.0 and V4.7.1 released February 3, 2008 + Updated all IAR ARM projects to use V5.11 of the IAR Embedded Workbench for ARM. + Introduced recursive semaphore feature. + Updated LPC2368 demos to take into account silicon bugs in old chip revisions. + Updated STR9 uIP port to manually set the net mask and gateway addresses. + Updating demos to allow more to run with the co-operative scheduler. + Fixed co-operative scheduler behaviour upon the occurrence of a tick interrupt while the scheduler was suspended. + Updated documentation contained within semphr.h. + ARM7 GCC ports no longer use the IRQ attribute. Changes between V4.6.1 and V4.7.0 released December 6, 2007 + Introduced the counting semaphore macros and demo source files. The Open Watcom PC project has been updated to include the new demo. See the online documentation for more information. + Introduced the 'alternative' queue handling API and demo source files. The Open Watcom PC project has been updated to include the new demo source files. See the online documentation for more information. + Added AT91SAM7X Eclipse demo project. + Added the STM32 primer demo project for the GCC compiler and Ride IDE. + Removed the .lock files that were mistakenly included in the V4.6.1 eclipse workspaces. Changes between V4.6.0 and V4.6.1 released November 5 2007 + Added support for the MIPS M4K based PIC32. + Added 'extern "C"' to all the header files to facilitate use with C++. Changes between V4.5.0 and V4.6.0 released October 28 2007 + Changed the method used to force a context switch within an ISR for the ARM7/9 GCC ports only. The portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros are no longer supported. This is to ensure correct behaviour no matter which GCC version is used, with or without the -fomit-frame-pointer option, and at all optimisation levels. + Corrected the prototype for xQueueGenericSend() within queue.h. Changes between V4.4.0 and V4.5.0 released September 17 2007 + Added the xQueueSendToFront(), xQueueSendToBack() and xQueuePeek() functionality. These should now be used in preference to the old xQueueSend() function - which is maintained for backward compatibility. + Added Mutex functionality. The behaviour of mutexes is subtly different to the already existing binary semaphores as mutexes automatically include a priority inheritance mechanism. + Added the GenQTest.c and QPeek.c to test and demonstrate the behaviour of the new functionality. + Updated the LM3Sxxxx and PC ports to include the new GenQTest.c and QPeek.c files. + Updated the GCC port for the Cortex M3 to include the configKERNEL_INTERRUPT_PRIORITY functionality. This was previously only included in the IAR port. + Optimised the GCC and IAR port layer code - specifically the context switch code. + Consolidated the LM3Sxxxx EK demos for all development tools into a single project that automatically detects which version of the EK the application is executing on. + Added Eclipse support for LM3Sxxxx evaluation kits. + Added Eclipse support for the Keil LPC2368 evaluation kit. + Added the Demo/Drivers directory to hold code that is common to multiple demo application projects. + Included some minor bug fixes in the uIP 1.0 code. + Added an lwIP demo for the STR9 - thanks ST for assistance. + Updated the AVR32 port to ensure correct behaviour with full compiler optimisation. + Included binaries for OpenOCD FTDI and parallel port interfaces. Changes between V4.4.0 and V4.3.1 released July 31, 2007 + Added AVR32 UC3B demo application. + Updated AVR32 UC3A port and demo applications. + Added IAR lwIP demo for AVR32 UC3A. + Updated listGET_OWNER_OF_NEXT_ENTRY() to assist compiler optimisation (thanks Niu Yong for making the suggestion). + Added xTaskGetSchedulerState() API function. + BUG FIX: Corrected behaviour when tasks that are blocked indefinitely have their block time adjusted (within xQueueSend() and xQueueReceive()), and are the subject of a call the vTaskResume() when they are not actually in the Suspended state (thanks Dan Searles for reporting the issues). Changes between V4.3.0 and V4.3.1 released June 11, 2007 + Added STMicroelectronics STM32 Cortex-M3 demo application. + Updated ustdlib.c for the GCC LM3S6965 demo. Changes between V4.2.1 and V4.3.0 released June 5, 2007 + Introduced configKERNEL_INTERRUPT_PRIORITY to the IAR Cortex-M3, PIC24 and dsPIC ports. See the LM3S6965 and PIC24 demo application documentation pages for more information. + Updated the PIC24 and dsPIC demos to build with V3.0 of the PIC30 GCC tools, and changed the demo applications. + Added demos for the new Ethernet and CAN enabled Luminary Micro Stellaris microcontrollers. + Corrected bug in uIP the demos that prevented frames of approximately 1480 bytes and over from being transmitted. + Included the LPC2368/uIP/Rowley demo into the main FreeRTOS.org download. + Update to WizC PIC18 port to permit its use with version 14 of the compiler. Thanks Marcel! Changes between V4.2.1 and V4.2.0 released April 2, 2007 + Added AVR32 AT32UC3A ports for GCC and IAR. + Added -fomit-frame-pointer option to lwIP SAM7X demo makefile. + Moved location of call to LCD_Init() in STR9 demo to ensure it is only called after the scheduler has been started. Changes between V4.1.3 and V4.2.0 released February 8, 2007 + Changes to both task.c and queue.c as a result of testing performed on the SafeRTOS code base. + Added Cortex-M3 LM3S811 demos for GCC and IAR tools. Changes between V4.1.2 and V4.1.3 released November 19, 2006 + Added STR750 ARM7 port using the Raisonance RIDE/GCC tools. + Added -fomit-frame-pointer option to Rowley ARM7 demos as work around to GCC bug at some optimisation levels. + Altered the way the heap is defined in the LM3S811 Keil demo to prevent the RAM usage from counting toward the code size limit calculation. + CO-ROUTINE BUG FIX: Removed the call to prvIsQueueEmpty from within xQueueCRReceive as it exited with interrupts enabled. Thanks Paul Katz. + Tasks that block on events with a timeout of portMAX_DELAY are now blocked indefinitely if configINCLUDE_vTaskSuspend is defined. Previously portMAX_DELAY was just the longest block time possible. This is still the case if configINCLUDE_vTaskSuspend is not defined. + Minor changes to some demo application files. Changes between V4.1.1 and V4.1.2 released October 21, 2006 + Added 16bit PIC ports and demos. + Added STR750 port and demo. Changes between V4.1.0 and V4.1.1 released September 24, 2006 + Added the Luminary Micro Stellaris LM3S811 demo application. Changes between V4.0.5 and V4.1.0 released August 28, 2006 + Prior to V4.1.0, under certain documented circumstances, it was possible for xQueueSend() and xQueueReceive() to return without having completed and without their block time expiring. The block time effectively stated a maximum block time, and the return value of the function needed to be checked to determine the reason for returning. This is no longer the case as the functions will only return once the block time has expired or they are able to complete their operation. It is therefore no longer necessary to wrap calls within loops. + Changed the critical section handling in the IAR AVR port to correct the behaviour when used with later compiler versions. + Added the LPC2138 CrossWorks demo into the zip file. Previously this was only available as a separate download. + Modified the AVR demo applications to demonstrate the use of co-routines. Changes between V4.0.4 and V4.0.5 released August 13, 2006 + Introduced API function xTaskResumeFromISR(). Same functionality as xTaskResume(), but can be called from within an interrupt service routine. + Optimised vListInsert() in the case when the wake time is the maximum tick count value. + Bug fix: The 'value' of the event list item is updated when the priority of a task is changed. Previously only the priority of the TCB itself was changed. + vTaskPrioritySet() and vTaskResume() no longer use the event list item. This has not been necessary since V4.0.1 when the xMissedYield handling was added. + Lowered the PCLK setting on the ARM9 STR9 demo from 96MHz to 48MHz. + When ending the scheduler - do not try to attempt a context switch when deleting the current task. + SAM7X EMAC drivers: Corrected the Rx frame length mask when obtaining the length from the rx descriptor. Changes between V4.0.3 and V4.0.4 released June 22, 2006 + Added a port and demo application for the STR9 ARM9 based processors from ST. + Slight optimisation to the vTaskPrioritySet() function. + Included the latest uIP version (1.0) in the demo/common/ethernet directory. Changes between V4.0.2 and V4.0.3 released June 7, 2006 + Added a port and demo application for the Cortex-M3 target using the IAR development tools. + The ARM Cortex-m3 Rowley projects have been updated to use V1.6 of the CrossStudio tools. + The heap size defined for the lwIP Rowley demo has been reduced so that the project will link correctly when using the command line GCC tools also. The makefile has also been modified to allow debugging. + The lwIP Rowley demo not includes a 'kernel aware' debug window. + The uIP Rowley project has been updated to build with V1.6 of CrossWorks. + The second set of tasks in the blockQ demo were created the wrong way around (inconsistent to the description in the file). This has been corrected. Changes between V4.0.1 and V4.0.2 released May 28, 2006 + Port and demo application added for the Tern Ethernet Engine controller. + Port and demo application added for MC9S12 using GCC, thanks to Jefferson "imajeff" Smith. + The function vTaskList() now suspends the scheduler rather than disabling interrupts during the creation of the task list. + Allow a task to delete itself by passing in its own handle. Previously this could only be done by passing in NULL. + Corrected the value passed to the WDG_PeriodValueConfig() library function in the STR71x demo. + The tick hook function is now called only within a tick isr. Previously it was also called when the tick function was called during the scheduler unlocking process. + The EMAC driver in the SAM7X lwIP demo has been made more robust as per the thread: https://sourceforge.net/forum/message.php?msg_id=3714405 + In the PC ports: Add function prvSetTickFrequencyDefault() to set the DOS tick back to its proper value when the scheduler exits. Thanks Raynald! + In the Borland x86 ports there was a mistake in the portFIRST_CONTEXT macro where the BP register was not popped from the stack correctly. The BP value would never get used so this did not cause a problem, but it has been corrected all the same. Changes between V4.0.0 and V4.0.1 released April 7 2006 + Improved the ARM CORTEX M3 ports so they now only have to service pendSV interrupts. + Added a Luminary Micro port and demo for use with Rowley CrossWorks. + Added the xMissedYield handling to tasks.c. Changes between V3.2.4 and V4.0.0 Major changes: + Added new RTOS port for Luminary Micros ARM CORTEX M3 microcontrollers. + Added new co-routine functionality. Other kernel changes: + An optional tick hook call is now included in the tick function. + Introduced the xMiniListItem structure and removed the list pxHead member in order to reduce RAM usage. + Added the following definitions to the FreeRTOSConfig.h file included with every port: configUSE_TICK_HOOK configUSE_CO_ROUTINES configMAX_CO_ROUTINE_PRIORITIES + The volatile qualification has been changed on the list members to allow the task.c code to be tidied up a bit. + The scheduler can now be started even if no tasks have been created! This is to allow co-routines to run when there are no tasks. + A task being woken by an event will now preempt the currently running task even if its priority is only equal to the currently running task. Port and demo application changes: + Updated the WinAVR demo to compile with the latest version of WinAVR with no warnings generated. + Changed the WinAVR makefile to make chars signed - needed for the co-routine code if BaseType_t is set to char. + Added new demo application file crflash.c. This demonstrates co-routine functionality including passing data between co-routines. + Added new demo application file crhook.c. This demonstrates co-routine and tick hook functionality including passing data between and ISR and a co-routine. + Some NOP's were missing following stmdb{}^ instructions in various ARM7 ports. These have been added. + Updated the Open Watcom PC demo project to include the crflash and crhook demo co-routines as an example of their use. + Updated the H8S demo to compile with the latest version of GCC. + Updated the SAM7X EMAC drivers to take into account the hardware errata regarding lost packets. + Changed the default MAC address used by some WEB server demos as the original addresses used was not liked by some routers. + Modified the SAM7X/IAR startup code slightly to prevent it hanging on some systems when the code is executed using a j-link debugger. The j-link macro file configures the PLL before the code executes so attempting to configure it again in the startup code was causing a problem for some user. Now a check is performed first to see if the PLL is already set up. + GCC port now contain all assembler code in a single asm block rather than individual blocks as before. + GCC LPC2000 code now explicitly uses R0 rather than letting the assembler choose the register to use as a temporary register during the context switch. + Added portNOP() macro. + The compare match load value on LPC2000 ports now has 1 added to correct the value used. + The minimal stack depth has been increased slightly on the WIZC PIC18 port. Changes between V3.2.3 and V3.2.4 + Modified the GCC ARM7 port layer to allow use with GCC V4.0.0 and above. Many thanks to Glen Biagioni for the provided update. + Added a new Microblaze port and demo application. + Modified the SAM7X EMAC demo to default to use the MII interface rather than the RMII interface. + Modified the startup sequence of the SAM7X demo slightly to allow the EMAC longer to auto negotiate. Changes between V3.2.2 and V3.2.3 + Added MII interface support to the SAM7X EMAC peripheral driver. Previously versions worked with the RMII interface only. + Added command line GCC support to the SAM7X lwIP demo. Previously the project could only be built using the CrossWorks IDE. Modifications to this end include the addition of a standard makefile and linker script to the download, and some adjustments to the stacks allocated to each task. + Changed the page returned by the lwIP WEB server demo to display the task status table rather than the TCP/IP statistics. + Corrected the capitalisation of some header file includes and makefile dependencies to facilitate use on Linux host computers. + The various LPC2000 ports had a mistake in the timer setup where the prescale value was written to T0_PC instead of T0_PR. This would have no effect unless a prescale value was actually required. This has been corrected. Changes between V3.2.1 and V3.2.2 - Released 23 September, 2005 + Added an IAR port for the Philips LPC2129 + The Atmel ARM7 IAR demo project files are now saved in the IAR Embedded Workbench V4.30a format. + Updated the J-Link macro file included with the SAM7X uIP demo project to allow the demo board to be reset over the J-Link. Changes between V3.2.0 and V3.2.1 - Released 1 September, 2005 + Added lwIP demo for AT91SAM7X using Rowley tools. + Added uIP demo for AT91SAM7X using IAR tools. + Added function xTaskGetCurrentTaskHandle(). + Renamed events.h to mevents.h to prevent it conflicting with the events.h generated automatically by the HCS12 processor expert utility. events.h is only used by the PC demo application. + Both PIC18 ports now initialise the TBLPTRU to 0 as this is the value expected by the compiler, and the compilers do not write to this register. + The HCS12 banked model demo now creates the 'suicide' tasks immediately prior to starting the scheduler. These tasks should be the last tasks to get started in order for the test to function correctly. Changes between V3.1.1 and V3.2.0 - Released 29 June, 2005 V3.2.0 introduces two new MSP430 ports and corrects a minor kernel issues. Thanks to Ares.qi for his input. + Added two MSP430 ports that use the Rowley CrossWorks development tools. One port just mirrors the existing GCC port. The other port was provided by Milos Prokic. Thanks! + V3.2.0 corrects the behavior when vTaskPrioritySet() or vTaskResume() are called while the scheduler is locked (by a call to vTaskSuspendAll()). When this is done the subject task now starts to execute immediately when the scheduler is unlocked if it has the highest priority that is ready to run. Previously there was a possibility that the task would not run until the next RTOS tick or call to portYIELD(). + Another similar small correction ensures that in the case where more than one task is blocked on a semaphore or queue, the task with the highest priority is guaranteed to be unblocked first. + Added a couple of more test tasks to the PC demo which cover the points above. Changes between V3.1.0 and V3.1.1 - Released 21st June, 2005 This release updates the HCS12 port. The common kernel code remains unchanged. + Updated the HCS12 port to support banking and introduced a demo application for the MC9S12DP256. The new demo application is located in the Demo/HCS12_CodeWarrior_banked directory. + The name of the directory containing the MC9S12F32 demo application has been changed to Demo/HCS12_CodeWarrior_small (as in 'small' memory model). + MC9S12F32 demo updated slightly to use the PLL. The CPU speed for the demo application is now 24MHz. Previously it was 8MHz. + The demo application file Demo/Common/Minimal/death.c has a slight alteration to prevent it using floating point variables. Changes between V3.0.0 and V3.1.0 - Released 11th June, 2005 + Added new ports for ST Microsystems STR71x, and Freescale HCS12 microcontrollers. Currently the HCS12 port is limited to the small memory model. Large memory models will be supported in the next release. + PIC18 wizC port updated. Thanks to Marcel van Lieshout for his continuing contribution. + The accuracy of the AVR port timer setup has been improved. Thanks to Thomas Krutmann for this contribution. + Added a new conditional compilation macro configIDLE_SHOULD_YIELD. See the WEB documentation for details. + Updated the CrossWorks uIP demo to build with V1.4 of CrossWorks. + Slight modification to the SAM7 release build configuration to correct an include path definition. + Updated the MPLAB PIC18 documentation to provide extra details on linker file configuration. Changes between V3.0.0 and V2.6.1 - Released 23rd April, 2005 V3.0.0 includes many enhancements, so this history list is broken into subsections as follows: API changes New ports Directory name changes Kernel and miscellaneous changes changes - API changes + Each port now defines BaseType_t as the data type that is most efficient for that architecture. The type BaseType_t is used extensively in API calls necessitating the following changes to the FreeRTOS API function prototypes. See the "New for V3.0.0" section of the FreeRTOS online documentation for full details of API changes. - New ports + The AT91FR40008 ARM7 port contributed by John Feller is now included in the download (thanks John!). + The PIC18 port for the wizC/fedC compiler contributed by Marcel van Lieshout is now included in the download (thanks Marcel!). + The IAR port for the AVR microcontroller has been upgraded to V3.0.0 and is now a supported port. - Directory name changes For consistency, and to allow integration of the new ports, the following directory names have been changed. + The source/portable/GCC/ARM7 directory has been renamed source/portable/GCC/ARM7_LPC2000 so it is compatible with the naming of other GCC ARM7 ports. + The Demo/PIC directory has been renamed Demo/PIC18_MPLAB to accommodate the wizC/fedC PIC port. + The demo applications for the two AVR ports no longer share the same directory. The WinAVR demo is in the Demo/AVR_ATMega323_WinAVR directory and the IAR port in the Demo/AVR_ATMega323_IAR directory. - Kernel and miscellaneous changes changes See the "New for V3.0.0" section of the FreeRTOS online documentation for more information. + Previously 'portmacro.h' contained some user editable definitions relating to the user application, and some fixed definitions relating specifically to the port being used. The application specific definitions have been removed from 'portmacro.h' and placed inside a new header file called 'FreeRTOSConfig.h'. 'portmacro.h' should now never be modified by the user. A 'FreeRTOSConfig.h' is now included in each of FreeRTOS/Demo subdirectories - as it's settings relate to the demo application rather than being specific to the port. + Introduced configUSE_IDLE_HOOK in idle task. + The idle task will yield when another idle priority task is ready to run. Previously the idle task would run to the end of its time slice regardless. + The idle task is now created when the scheduler is started. This requires less stack than the previous scheme where it was created upon creation of the first application task. + The function usPortCheckFreeStackSpace() has been renamed usTaskCheckFreeStackSpace() and moved from the portable layer to tasks.c. + Corrected spelling of portMINMAL_STACK_SIZE to portMINIMAL_STACK_SIZE. + The portheap.c file included with the AVR port has been deleted. The AVR demo now uses the standard heap1 sample memory allocator. + The GCC AVR port is now build using the standard make utility. The batch files used previously have been deleted. This means a recent version of WinAVR is required in order to create a binary suitable for source level debugging. + vTaskStartScheduler() no longer takes the configUSE_PREEMPTION constant as a parameter. Instead the constant is used directly within tasks.c and no parameter is required. + The header file 'FreeRTOS.h' has been created and is used to include 'projdefs.h', 'FreeRTOSConfig.h' and 'portable.h' in the necessary order. FreeRTOS.h can now be included in place of these other headers. + The header file 'errors.h' has been deleted. The definitions it contained are now located within 'projdefs.h'. + pvPortMalloc() now takes a size_t parameter as per the ANSI malloc(). Previously an unsigned short was used. + When resuming the scheduler a yield is performed if either a tick has been missed, or a task is moved from the pending ready list into a ready list. Previously a yield was not performed on this second condition. + In heap1.c an overflow check has been added to ensure the next free byte variable does not wrap around. + Introduced the portTASK_FUNCTION() and portTASK_FUNCTION_PROTO() macros. + The MPLAB PIC port now saved the TABLAT register in interrupt service routines. Changes between V2.6.0 and V2.6.1 - Released Feb 22, 2005 This version adds support for the H8 processor. Other changes: + tskMAX_TASK_NAME_LEN removed from the task.h header and added to each individual portmacro.h file as portMAX_TASK_NAME_LEN. This allows RAM limited ports to allocate fewer characters to the task name. + AVR port - Replaced the inb() and outb() functions with direct memory access. This allows the port to be built with the 20050414 build of WinAVR. + GCC LPC2106 port - removed the 'static' from the definition of vNonPreemptiveTick() to allow the demo to link when using the cooperative scheduler. + GCC LPC2106 port - Corrected the optimisation options in the batch files ROM_THUMB.bat, RAM_THUMB.bat, ROM_ARM.bat and RAM_ARM.bat. The lower case -o is replaced by an uppercase -O. + Tasks.c - The strcpy call has been removed when copying across the task name into the TCB. + Updated the trace visualisation to always be 4 byte aligned so it can be used on ARM architectures. + There are now two tracecon executables (that convert the trace file binary into an ASCII file). One for big endian targets and one for little endian targets. + Added ucTasksDeleted variable to prevent vTaskSuspendAll() being called too often in the idle task. + SAM7 USB driver - Replaced the duplicated RX_DATA_BK0 in the interrupt mask with the RX_DATA_BK1. Changes between V2.5.5 and V2.6.0 - Released January 16, 2005 + Added the API function vTaskDelayUntil(). The demo app file Demo/Common/Minimal/flash.c has been updated to demonstrate its use. + Added INCLUDE_vTaskDelay conditional compilation. + Changed the name of the Demo/ARM7_AtmelSAM7S64_IAR directory to Demo/ARM7_AT91SAM7S64_IAR for consistency. + Modified the AT91SAM7S USB driver to allow descriptors that have a length that is an exact multiple of the FIFO to be transmitted. Changes between V2.5.4 and V2.5.5 - Released January 3, 2005 This version adds support for the Atmel SAM7 ARM7 microcontrollers along with the IAR development tools. Other changes: + Renamed the Demo/ARM7 directory to Demo/ARM7_LPC2106_GCC. + Renamed the Demo/ARM7_Keil directory to Demo/ARM7_LPC2129_Keil. + Modified the Philips ARM7 serial interrupt service routines to only process one interrupt per call. This seems to enable the ISR to operate more quickly. + Removed the 'far' keyword from the Open Watcom portable layer source files. This allows their use with V1.3 of Open Watcom. + Minor modifications to the SDCC build files to allow their use under Linux. Thanks to Frieder Ferlemann for this contribution. + Small change to sTaskCreate() to allow a context switch even when pxCreatedTask is NULL. Thanks to Kamil for this contribution. + inline keyword removed from vTaskSwitchContext() and VTaskIncrementTick() definitions. Changes between V2.5.3 and V2.5.4 - Released Dec 1, 2004 This is an important maintenance release. The function cTaskResumeAll() has been modified so it can be used safely prior to the kernel being initialised. This was an issue as cTaskResumeAll() is called from pvPortMalloc(). Thanks to Daniel Braun for highlighting this issue. Changes between V2.5.2 and V2.5.3 - Released Nov 2, 2004 The critical section handling functions have been changed for the GCC ARM7 port. Some optimisation levels use the stack differently to others. This means the interrupt flags cannot always be stored on the stack and are instead now stored in a variable, which is then saved as part of the tasks context. This allows the GCC ARM7 port to be used at all optimisation levels - including -Os. Other minor changes: + MSP430 definition of usCriticalNesting now uses the volatile qualifier. This is probably not required but added just in case. Changes between V2.5.1 and V2.5.2 - Released Oct 26, 2004 + Added the Keil ARM7 port. + Slight modification to comtest.c to make the delay periods more random. This creates a better test condition. Changes between V2.5.0 and V2.5.1 - Released Oct 9, 2004 + Added the MSP430 port. + Extra comments added to the GCC ARM7 port.c and portISR.c files. + The memory pool allocated within heap_1.c has been placed within a structure to ensure correct memory alignment on 32bit systems. + Within the GCC ARM7 serial drivers an extra check is made to ensure the post to the queue was successful if then attempting immediately retrieve the posted character. + Changed the name of the constant portTICKS_PER_MS to portTICK_PERIOD_MS as the old name was misleading. Changes between V2.4.2 and V2.5.0 - Released Aug 12, 2004 The RTOS source code download now includes three separate memory allocation schemes - so you can choose the most appropriate for your application. These are found in the Source/Portable/MemMang directory. The demo application projects have also been updated to demonstrate the new schemes. See the "Memory Management" page of the API documentation for more details. + Added heap_1.c, heap_2.c and heap_3.c in the Source/Portable/MemMang directory. + Replaced the portheap.c files for each demo application with one of the new memory allocation files. + Updated the portmacro.h file for each demo application to include the constants required for the new memory allocators: portTOTAL_HEAP_SIZE and portBYTE_ALIGNMENT. + Added a new test to the ARM7 demo application that tests the operation of the heap_2 memory allocator. Changes between V2.4.1 and V2.4.2 - Released July 14, 2004 + The ARM7 port now supports THUMB mode. + Modification to the ARM7 demo application serial port driver. Changes between V2.4.0 and V2.4.1 - Released July 2, 2004 + Rationalised the ARM7 port version of portEXIT_CRITICAL() - improvements provided by Bill Knight. + Made demo serial driver more complete and robust. Changes between V2.4.0 and V2.3.1 - Released June 30, 2004 + Added the first ARM7 port - thanks to Bill Knight for the assistance provided. + Added extra files to the Demo/Common/Minimal directory. These are equivalent to their Demo/Common/Full counterparts but with the calls to the functions defined in print.c removed. + Added TABLAT to the list of registers saved as part of a PIC18 context. Changes between V2.3.0 and V2.3.1 - Released June 25, 2004 + Changed the way the vector table is defined to be more portable. + Corrected the definitions of SPH and SPL in portmacro.s90. The previous definitions prevented V2.3.0 operating if the iom323.h header file was included in portmacro.s90. Changes between V2.2.0 and V2.3.0 - Released June 19, 2004 + Added an AVR port that uses the IAR compiler. + Explicit use of 'signed' qualifier on plain char types. + Modified the Open Watcom project files to use 'signed' as the default char type. + Changed odd calculation of initial pxTopOfStack value when portSTACK_GROWTH < 0. + Added inline qualifier to context switch functions within task.c. Ports that do not support the (non ANSI) inline keyword have the inline #define'd away in their respective portmacro.h files. Changes between V2.1.1 and V2.2.0 - Released May 18, 2004 + Added Cygnal 8051 port. + PCLATU and PCLATH are now saved as part of the PIC18 context. This allows function pointers to be used within tasks. Thanks to Javier Espeche for the enhancement. + Minor changes to demo application files to reduce stack usage. + Minor changes to prevent compiler warnings when compiling the new port. Changes between V2.1.0 and V2.1.1 - Released March 12, 2004 + Bug fix - pxCurrentTCB is now initialised before the call to prvInitialiseTaskLists(). Previously pxCurrentTCB could be accessed while null during the initialisation sequence. Thanks to Giuseppe Franco for the correction. Changes between V2.0.0 and V2.1.0 - Released Feb 29, 2004 V2.1.0 has significant reworks that greatly reduce the amount of time the kernel has interrupts disabled. The first section of modifications listed here must be taken into account by users. The second section are related to the kernel implementation and as such are transparent. Section1 : + The typedef TickType_t has been introduced. All delay times should now use a variable of type TickType_t in place of the unsigned long's used previously. API function prototypes have been updated appropriately. + The configuration macro USE_16_BIT_TICKS has been introduced. If set to 1 TickType_t is defined as an unsigned short. If set to 0 TickType_t is defined as an unsigned long. See the configuration section of the API documentation for more details. + The configuration macro INCLUDE_vTaskSuspendAll is now obsolete. + vTaskResumeAll() has been renamed cTaskResumeAll() as it now returns a value (see the API documentation). + ulTaskGetTickCount() has been renamed xTaskGetTickCount() as the type it returns now depends on the USE_16_BIT_TICKS definition. + cQueueReceive() must now >never< be used from within an ISR. Use the new cQueueReceiveFromISR() function instead. Section 2: + A mechanism has been introduced that allows a queue to be accessed by a task and ISR simultaneously. + A "pending ready" queue has been introduced that enables interrupts to be processed when the scheduler is suspended. + The list implementation has been improved to provide faster item removal. + The scheduler now makes use of the scheduler suspend mechanism in places where previously interrupts were disabled. Changes between V1.2.6 and V2.0.0 - Released Jan 31, 2004 + Introduced new API functions: vTaskPriorityGet () vTaskPrioritySet () vTaskSuspend () vTaskResume () vTaskSuspendAll () vTaskResumeAll () + Added conditional compilation options that allow the components of the kernel that are unused by an application to be excluded from the build. See the Configuration section on the WEB site for more information (on the API pages). The macros have been added to each portmacro.h file ( sometimes called prtmacro.h). + Rearranged tasks.c. + Added demo application file dynamic.c. + Updated the PC demo application to make use of dynamic.c. + Updated the documentation contained in the kernel header files. + Creating a task now causes a context switch if the task being created has a higher priority than the calling task - assuming the kernel is running. + vTaskDelete() now only causes a context switch if the calling task is the task being deleted. Changes between V1.2.5 and V1.2.6 - Released December 31, 2003 Barring the change to the interrupt vector (PIC port) these are minor enhancements. + The interrupt vector used for the PIC master ISR has been changed from 0x18 to 0x08 - where it should have always been. The incorrect address still works but probably executes a number of NOP's before getting to the ISR. + Changed the baud rate used by the AVR demo application to 38400. This has an error percentage of less than one percent with an 8MHz clock. + Raised the priority of the Rx task in demo\full\comtest.c. This only affects the Flashlite and PC ports. This was done to prevent the Rx buffer becoming full. + Reverted the Flashlite COM port driver back so it does not use the DMA. The DMA appears to miss characters under stress. The Borland Flashlite port was also calculating a register value incorrectly resulting in the wrong DMA source address being used. The same code worked fine when compiling with Open Watcom. Other minor enhancements were made to the interrupt handling. + Modified the PIC serial Rx ISR to check for and clear overrun errors. Overrun errors seem to prevent any further characters being received. + The PIC demo projects now have some optimisation switched on. Changes between V1.2.4 and V1.2.5 Small fix made to the PIC specific port.c file described below. + Introduced portGLOBAL_INTERRUPT_FLAG definition to test the global interrupt flag setting. Using the two bits defined within portINITAL_INTERRUPT_STATE was causing the w register to get clobbered before the test was performed. Changes between V1.2.3 and V1.2.4 V1.2.4 contains a release version of the PIC18 port. An optional exception has been included with the GPL. See the licensing section of www.FreeRTOS.org for details. + The function xPortInitMinimal() has been renamed to xSerialPortInitMinimal() and the function xPortInit() has been renamed to xSerialPortInit(). + The function sSerialPutChar() has been renamed cSerialPutChar() and the function return type chaned to portCHAR. + The integer and flop tasks now include calls to tskYIELD(), allowing them to be used with the cooperative scheduler. + All the demo applications now use the integer and comtest tasks when the cooperative scheduler is being used. Previously they were only used with the preemptive scheduler. + Minor changes made to operation of minimal versions of comtest.c and integer.c. + The ATMega port definition of portCPU_CLOSK_HZ definition changed to 8MHz base 10, previously it base 16. Changes between V1.2.2a and V1.2.3 The only change of any significance is to the license, which has changed from the Open Software License to the GNU GPL. The zip file also contains a pre-release version of the PIC18 port. This has not yet completed testing and as such does not constitute part of the V1.2.3 release. It is still however covered by the GNU GPL. There are minor source code changes to accommodate the PIC C compiler. These mainly involve more explicit casting. + sTaskCreate() has been modified slightly to make use of the portSTACK_GROWTH macro. This is required for the PIC port where the stack grows in the opposite direction to the other existing ports. + prvCheckTasksWaitingTermination() has been modified slightly to bring the decrementing of usCurrentNumberOfTasks within the critical section, where it should have been since the creation of an eight bit port. Changes between V1.2.2 and V1.2.2a The makefile and buildcoff.bat files included with the AVR demo application have been modified for use with the September 2003 build of WinAVR. No source files have changed. Changes between V1.2.1 and V1.2.2 There are only minor changes here to allow the PC and Flashlite 186 ports to use the Borland V4.52 compiler, as supplied with the Flashlite 186 development kit. + Introduced a BCC directory under source\portable. This contains all the files specific to the Borland compiler port. + Corrected the macro naming of portMS_PER_TICK to portTICKS_PER_MS. + Modified comtest.c to increase the rate at which the string is transmitted and received on the serial port. The Flashlite 186 demo app baud rate has also been increased. + The values of the constants used in both integer.c files have been increased to force the Borland compiler to use 32 bit values. The Borland optimiser placed the previous values in 16 bit registers, and in So doing invalidated the test. Changes between V1.2.0 and V1.2.1 This version includes some minor changes to the list implementation aimed at improving the context switch time - with is now approximately 10% faster. Changes include the removal of some null pointer assignment checks. These were redundant where the scheduler uses the list functions, but means any user application choosing to use the same list functions must now check that no NULL pointers are passed as a parameter. The Flashlite 186 serial port driver has also been modified to use a DMA channel for transmissions. The serial driver is fully functional but still under development. Flashlite users may prefer to use V1.2.0 for now. Details: + Changed the baud rate for the ATMega323 serial test from 19200 to 57600. + Use vSerialPutString() instead of single character puts in Demo\Full\Comtest.c. This allows the use of the flashlite DMA serial driver. Also the check variable only stops incrementing after two consecutive failures. + semtest.c creates four tasks, two of which operate at the idle priority. The tasks that operate at the idle priority now use a lower expected count than those running at a higher priority. This prevents the low priority tasks from signalling an error because they have not been scheduled enough time for each of them to count the shared variable to the higher original value. + The flashlite 186 serial driver now uses a DMA channel for transmissions. + Removed the volatile modifier from the list function parameters. This was only ever included to prevent compiler warnings. Now warnings are removed by casting parameters where the calls are made. + prvListGetOwnerOfNextEntry() and prvListGetOwnerOfHeadEntry() have been removed from list.c and added as macros in list.h. + usNumberOfItems has been added to the list structure. This removes the need for a pointer comparison when checking if a list is empty, and so is slightly faster. + Removed the NULL check in vListRemove(). This makes the call faster but necessitates any application code utilising the list implementation to ensure NULL pointers are not passed. + Renamed portTICKS_PER_MS definition to portMS_PER_TICK (milli seconds per tick). This is what it always should have been. Changes between V1.01 and V1.2.0 The majority of these changes were made to accommodate the 8bit AVR port. The scheduler workings have not changed, but some of the data types used have been made more friendly to an eight bit environment. Details: + Changed the version numbering format. + Added AVR port. + Split the directory demo\common into demo\common\minimal and demo\common\full. The files in the full directory are for systems with a display (currently PC and Flashlite 186 demo's). The files in the minimal directory are for systems with limited RAM and no display (currently MegaAVR). + Minor changes to demo application function prototypes to make more use of 8bit data types. + Within the scheduler itself the following functions have slightly modified declarations to make use of 8bit data types where possible: xQueueCreate(), sQueueReceive(), sQUeueReceive(), usQueueMessageWaiting(), sQueueSendFromISR(), sSemaphoreTake(), sSemaphoreGive(), sSemaphoreGiveFromISR(), sTaskCreate(), sTaskMoveFromEventList(). Where the return type has changed the function name has also changed in accordance with the naming convention. For example usQueueMessageWaiting() has become ucQueueMessageWaiting(). + The definition tskMAX_PRIORITIES has been moved from task.h to portmacro.h and renamed portMAX_PRIORITIES. This allows different ports to allocate a different maximum number of priorities. + By default the trace facility is off, previously USE_TRACE_FACILITY was defined. + comtest.c now uses a psuedo random delay between sends. This allows for better testing as the interrupts do not arrive at regular intervals. + Minor change to the Flashlite serial port driver. The driver is written to demonstrate the scheduler and is not written to be efficient. Changes between V1.00 and V1.01 These changes improve the ports. The scheduler itself has not changed. Improved context switch mechanism used when performing a context switch from an ISR (both the tick ISR and the serial comms ISR's within the demo application). The new mechanism is faster and uses less stack. The assembler file portasm.asm has been replaced by a header file portasm.h. This includes a few assembler macro definitions. All saving and restoring of registers onto/off of the stack is now handled by the compiler. This means the initial stack setup for a task has to mimic the stack used by the compiler, which is different for debug and release builds. Slightly changed the operation of the demo application, details below. Details: + portSWITCH_CONTEXT() replaced by vPortFirstContext(). + pxPortInitialiseStack() modified to replicate the stack used by the compiler. + portasm.asm file removed. + portasm.h introduced. This contains macro definitions for portSWITCH_CONTEXT() and portFIRST_CONTEXT(). + Context switch from ISR now uses the compiler generated interrupt mechanism. This is done simply by calling portSWITCH_CONTEXT and leaving the save/restore to compiler generated code. + Calls to taskYIELD() during ISR's have been replaced by calling the simpler and faster portSWITCH_CONTEXT(). + The Flashlite 186 port now uses 186 instruction set (used to use 80x86 instructions only). + The blocking queue tasks within the demo application did not operate quite as described. This has been corrected. + The priority of the comtest Rx task within the demo application has been lowered. Received characters are now processed (read from the queue) at the idle priority, allowing low priority tasks to run evenly at times of a high communications overhead. + Prevent the call to kbhit() in main.c for debug builds as the debugger seems to have problems stepping over the call. This if for the PC port only. ================================================ FILE: FreeRTOS-comparison/LICENSE.md ================================================ MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: FreeRTOS-comparison/Quick_Start_Guide.url ================================================ [InternetShortcut] URL=https://www.FreeRTOS.org/FreeRTOS-quick-start-guide.html IDList= [{000214A0-0000-0000-C000-000000000046}] Prop3=19,2 ================================================ FILE: FreeRTOS-comparison/README.md ================================================ > NOTE
This directory is the FreeRTOS Kernel part of the FreeRTOS 202210 LTS distribution. To reduce the size, the `portable` sub-directory has been pruned and several FreeRTOS ports have been removed. Quantum Leaps, March 4, 2023 ## 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. 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). ### 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). ## Cloning this repository To clone using HTTPS: ``` git clone https://github.com/FreeRTOS/FreeRTOS-Kernel.git ``` Using SSH: ``` git clone git@github.com:FreeRTOS/FreeRTOS-Kernel.git ``` ## Repository structure - The root of this repository contains the three files that are common to every port - list.c, queue.c and tasks.c. The kernel is contained within these three files. croutine.c implements the optional co-routine functionality - which is normally only used on very memory limited systems. - The ```./portable``` directory contains the files that are specific to a particular microcontroller and/or compiler. See the readme file in the ```./portable``` directory for more information. - The ```./include``` directory contains the real time kernel header files. ### Code Formatting FreeRTOS files are formatted using the "uncrustify" tool. The configuration file used by uncrustify can be found in the [FreeRTOS/FreeRTOS repository](https://github.com/FreeRTOS/FreeRTOS/blob/main/tools/uncrustify.cfg). ### Spelling *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*. Note that only the FreeRTOS Kernel source files are checked for proper spelling, the portable section is ignored. ================================================ FILE: FreeRTOS-comparison/croutine.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #include "FreeRTOS.h" #include "task.h" #include "croutine.h" /* Remove the whole file is co-routines are not being used. */ #if ( configUSE_CO_ROUTINES != 0 ) /* * Some kernel aware debuggers require data to be viewed to be global, rather * than file scope. */ #ifdef portREMOVE_STATIC_QUALIFIER #define static #endif /* Lists for ready and blocked co-routines. --------------------*/ static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */ static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ static List_t * pxDelayedCoRoutineList = NULL; /*< Points to the delayed co-routine list currently being used. */ static List_t * pxOverflowDelayedCoRoutineList = NULL; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ /* Other file private variables. --------------------------------*/ CRCB_t * pxCurrentCoRoutine = NULL; static UBaseType_t uxTopCoRoutineReadyPriority = 0; static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; /* The initial state of the co-routine when it is created. */ #define corINITIAL_STATE ( 0 ) /* * Place the co-routine represented by pxCRCB into the appropriate ready queue * for the priority. It is inserted at the end of the list. * * This macro accesses the co-routine ready lists and therefore must not be * used from within an ISR. */ #define prvAddCoRoutineToReadyQueue( pxCRCB ) \ { \ if( ( pxCRCB )->uxPriority > uxTopCoRoutineReadyPriority ) \ { \ uxTopCoRoutineReadyPriority = ( pxCRCB )->uxPriority; \ } \ vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ ( pxCRCB )->uxPriority ] ), &( ( pxCRCB )->xGenericListItem ) ); \ } /* * Utility to ready all the lists used by the scheduler. This is called * automatically upon the creation of the first co-routine. */ static void prvInitialiseCoRoutineLists( void ); /* * Co-routines that are readied by an interrupt cannot be placed directly into * the ready lists (there is no mutual exclusion). Instead they are placed in * in the pending ready list in order that they can later be moved to the ready * list by the co-routine scheduler. */ static void prvCheckPendingReadyList( void ); /* * Macro that looks at the list of co-routines that are currently delayed to * see if any require waking. * * Co-routines are stored in the queue in the order of their wake time - * meaning once one co-routine has been found whose timer has not expired * we need not look any further down the list. */ static void prvCheckDelayedList( void ); /*-----------------------------------------------------------*/ BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ) { BaseType_t xReturn; CRCB_t * pxCoRoutine; /* Allocate the memory that will store the co-routine control block. */ pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) ); if( pxCoRoutine ) { /* If pxCurrentCoRoutine is NULL then this is the first co-routine to * be created and the co-routine data structures need initialising. */ if( pxCurrentCoRoutine == NULL ) { pxCurrentCoRoutine = pxCoRoutine; prvInitialiseCoRoutineLists(); } /* Check the priority is within limits. */ if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) { uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; } /* Fill out the co-routine control block from the function parameters. */ pxCoRoutine->uxState = corINITIAL_STATE; pxCoRoutine->uxPriority = uxPriority; pxCoRoutine->uxIndex = uxIndex; pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; /* Initialise all the other co-routine control block parameters. */ vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); /* Set the co-routine control block as a link back from the ListItem_t. * This is so we can get back to the containing CRCB from a generic item * in a list. */ listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); /* Event lists are always in priority order. */ listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) ); /* Now the co-routine has been initialised it can be added to the ready * list at the correct priority. */ prvAddCoRoutineToReadyQueue( pxCoRoutine ); xReturn = pdPASS; } else { xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; } return xReturn; } /*-----------------------------------------------------------*/ void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t * pxEventList ) { TickType_t xTimeToWake; /* Calculate the time to wake - this may overflow but this is * not a problem. */ xTimeToWake = xCoRoutineTickCount + xTicksToDelay; /* We must remove ourselves from the ready list before adding * ourselves to the blocked list as the same list item is used for * both lists. */ ( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); /* The list item will be inserted in wake time order. */ listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); if( xTimeToWake < xCoRoutineTickCount ) { /* Wake time has overflowed. Place this item in the * overflow list. */ vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); } else { /* The wake time has not overflowed, so we can use the * current block list. */ vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); } if( pxEventList ) { /* Also add the co-routine to an event list. If this is done then the * function must be called with interrupts disabled. */ vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); } } /*-----------------------------------------------------------*/ static void prvCheckPendingReadyList( void ) { /* Are there any co-routines waiting to get moved to the ready list? These * are co-routines that have been readied by an ISR. The ISR cannot access * the ready lists itself. */ while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) { CRCB_t * pxUnblockedCRCB; /* The pending ready list can be accessed by an ISR. */ portDISABLE_INTERRUPTS(); { pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyCoRoutineList ) ); ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); } portENABLE_INTERRUPTS(); ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); } } /*-----------------------------------------------------------*/ static void prvCheckDelayedList( void ) { CRCB_t * pxCRCB; xPassedTicks = xTaskGetTickCount() - xLastTickCount; while( xPassedTicks ) { xCoRoutineTickCount++; xPassedTicks--; /* If the tick count has overflowed we need to swap the ready lists. */ if( xCoRoutineTickCount == 0 ) { List_t * pxTemp; /* Tick count has overflowed so we need to swap the delay lists. If there are * any items in pxDelayedCoRoutineList here then there is an error! */ pxTemp = pxDelayedCoRoutineList; pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; pxOverflowDelayedCoRoutineList = pxTemp; } /* See if this tick has made a timeout expire. */ while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) { pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) { /* Timeout not yet expired. */ break; } portDISABLE_INTERRUPTS(); { /* The event could have occurred just before this critical * section. If this is the case then the generic list item will * have been moved to the pending ready list and the following * line is still valid. Also the pvContainer parameter will have * been set to NULL so the following lines are also valid. */ ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) ); /* Is the co-routine waiting on an event also? */ if( pxCRCB->xEventListItem.pxContainer ) { ( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); } } portENABLE_INTERRUPTS(); prvAddCoRoutineToReadyQueue( pxCRCB ); } } xLastTickCount = xCoRoutineTickCount; } /*-----------------------------------------------------------*/ void vCoRoutineSchedule( void ) { /* Only run a co-routine after prvInitialiseCoRoutineLists() has been * called. prvInitialiseCoRoutineLists() is called automatically when a * co-routine is created. */ if( pxDelayedCoRoutineList != NULL ) { /* See if any co-routines readied by events need moving to the ready lists. */ prvCheckPendingReadyList(); /* See if any delayed co-routines have timed out. */ prvCheckDelayedList(); /* Find the highest priority queue that contains ready co-routines. */ while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) { if( uxTopCoRoutineReadyPriority == 0 ) { /* No more co-routines to check. */ return; } --uxTopCoRoutineReadyPriority; } /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines * of the same priority get an equal share of the processor time. */ listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); /* Call the co-routine. */ ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); } } /*-----------------------------------------------------------*/ static void prvInitialiseCoRoutineLists( void ) { UBaseType_t uxPriority; for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) { vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); } vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 ); vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 ); vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList ); /* Start with pxDelayedCoRoutineList using list1 and the * pxOverflowDelayedCoRoutineList using list2. */ pxDelayedCoRoutineList = &xDelayedCoRoutineList1; pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; } /*-----------------------------------------------------------*/ BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList ) { CRCB_t * pxUnblockedCRCB; BaseType_t xReturn; /* This function is called from within an interrupt. It can only access * event lists and the pending ready list. This function assumes that a * check has already been made to ensure pxEventList is not empty. */ pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) { xReturn = pdTRUE; } else { xReturn = pdFALSE; } return xReturn; } #endif /* configUSE_CO_ROUTINES == 0 */ ================================================ FILE: FreeRTOS-comparison/event_groups.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* FreeRTOS includes. */ #include "FreeRTOS.h" #include "task.h" #include "timers.h" #include "event_groups.h" /* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified * because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined * for the header files above, but not in this file, in order to generate the * correct privileged Vs unprivileged linkage and placement. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */ /* The following bit fields convey control information in a task's event list * item value. It is important they don't clash with the * taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */ #if configUSE_16_BIT_TICKS == 1 #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U #define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U #define eventWAIT_FOR_ALL_BITS 0x0400U #define eventEVENT_BITS_CONTROL_BYTES 0xff00U #else #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL #define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL #define eventWAIT_FOR_ALL_BITS 0x04000000UL #define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL #endif typedef struct EventGroupDef_t { EventBits_t uxEventBits; List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */ #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxEventGroupNumber; #endif #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */ #endif } EventGroup_t; /*-----------------------------------------------------------*/ /* * Test the bits set in uxCurrentEventBits to see if the wait condition is met. * The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is * pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor * are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the * wait condition is met if any of the bits set in uxBitsToWait for are also set * in uxCurrentEventBits. */ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) { EventGroup_t * pxEventBits; /* A StaticEventGroup_t object must be provided. */ configASSERT( pxEventGroupBuffer ); #if ( configASSERT_DEFINED == 1 ) { /* Sanity check that the size of the structure used to declare a * variable of type StaticEventGroup_t equals the size of the real * event group structure. */ volatile size_t xSize = sizeof( StaticEventGroup_t ); configASSERT( xSize == sizeof( EventGroup_t ) ); } /*lint !e529 xSize is referenced if configASSERT() is defined. */ #endif /* configASSERT_DEFINED */ /* The user has provided a statically allocated event group - use it. */ pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 !e9087 EventGroup_t and StaticEventGroup_t are deliberately aliased for data hiding purposes and guaranteed to have the same size and alignment requirement - checked by configASSERT(). */ if( pxEventBits != NULL ) { pxEventBits->uxEventBits = 0; vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) { /* Both static and dynamic allocation can be used, so note that * this event group was created statically in case the event group * is later deleted. */ pxEventBits->ucStaticallyAllocated = pdTRUE; } #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ traceEVENT_GROUP_CREATE( pxEventBits ); } else { /* xEventGroupCreateStatic should only ever be called with * pxEventGroupBuffer pointing to a pre-allocated (compile time * allocated) StaticEventGroup_t variable. */ traceEVENT_GROUP_CREATE_FAILED(); } return pxEventBits; } #endif /* configSUPPORT_STATIC_ALLOCATION */ /*-----------------------------------------------------------*/ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) EventGroupHandle_t xEventGroupCreate( void ) { EventGroup_t * pxEventBits; /* Allocate the event group. Justification for MISRA deviation as * follows: pvPortMalloc() always ensures returned memory blocks are * aligned per the requirements of the MCU stack. In this case * pvPortMalloc() must return a pointer that is guaranteed to meet the * alignment requirements of the EventGroup_t structure - which (if you * follow it through) is the alignment requirements of the TickType_t type * (EventBits_t being of TickType_t itself). Therefore, whenever the * stack alignment requirements are greater than or equal to the * TickType_t alignment requirements the cast is safe. In other cases, * where the natural word size of the architecture is less than * sizeof( TickType_t ), the TickType_t variables will be accessed in two * or more reads operations, and the alignment requirements is only that * of each individual read. */ pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */ if( pxEventBits != NULL ) { pxEventBits->uxEventBits = 0; vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) { /* Both static and dynamic allocation can be used, so note this * event group was allocated statically in case the event group is * later deleted. */ pxEventBits->ucStaticallyAllocated = pdFALSE; } #endif /* configSUPPORT_STATIC_ALLOCATION */ traceEVENT_GROUP_CREATE( pxEventBits ); } else { traceEVENT_GROUP_CREATE_FAILED(); /*lint !e9063 Else branch only exists to allow tracing and does not generate code if trace macros are not defined. */ } return pxEventBits; } #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ /*-----------------------------------------------------------*/ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) { EventBits_t uxOriginalBitValue, uxReturn; EventGroup_t * pxEventBits = xEventGroup; BaseType_t xAlreadyYielded; BaseType_t xTimeoutOccurred = pdFALSE; configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); configASSERT( uxBitsToWaitFor != 0 ); #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) { configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); } #endif vTaskSuspendAll(); { uxOriginalBitValue = pxEventBits->uxEventBits; ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet ); if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor ) { /* All the rendezvous bits are now set - no need to block. */ uxReturn = ( uxOriginalBitValue | uxBitsToSet ); /* Rendezvous always clear the bits. They will have been cleared * already unless this is the only task in the rendezvous. */ pxEventBits->uxEventBits &= ~uxBitsToWaitFor; xTicksToWait = 0; } else { if( xTicksToWait != ( TickType_t ) 0 ) { traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ); /* Store the bits that the calling task is waiting for in the * task's event list item so the kernel knows when a match is * found. Then enter the blocked state. */ vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait ); /* This assignment is obsolete as uxReturn will get set after * the task unblocks, but some compilers mistakenly generate a * warning about uxReturn being returned without being set if the * assignment is omitted. */ uxReturn = 0; } else { /* The rendezvous bits were not set, but no block time was * specified - just return the current event bit value. */ uxReturn = pxEventBits->uxEventBits; xTimeoutOccurred = pdTRUE; } } } xAlreadyYielded = xTaskResumeAll(); if( xTicksToWait != ( TickType_t ) 0 ) { if( xAlreadyYielded == pdFALSE ) { portYIELD_WITHIN_API(); } else { mtCOVERAGE_TEST_MARKER(); } /* The task blocked to wait for its required bits to be set - at this * point either the required bits were set or the block time expired. If * the required bits were set they will have been stored in the task's * event list item, and they should now be retrieved then cleared. */ uxReturn = uxTaskResetEventItemValue(); if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) { /* The task timed out, just return the current event bit value. */ taskENTER_CRITICAL(); { uxReturn = pxEventBits->uxEventBits; /* Although the task got here because it timed out before the * bits it was waiting for were set, it is possible that since it * unblocked another task has set the bits. If this is the case * then it needs to clear the bits before exiting. */ if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor ) { pxEventBits->uxEventBits &= ~uxBitsToWaitFor; } else { mtCOVERAGE_TEST_MARKER(); } } taskEXIT_CRITICAL(); xTimeoutOccurred = pdTRUE; } else { /* The task unblocked because the bits were set. */ } /* Control bits might be set as the task had blocked should not be * returned. */ uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; } traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ); /* Prevent compiler warnings when trace macros are not used. */ ( void ) xTimeoutOccurred; return uxReturn; } /*-----------------------------------------------------------*/ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) { EventGroup_t * pxEventBits = xEventGroup; EventBits_t uxReturn, uxControlBits = 0; BaseType_t xWaitConditionMet, xAlreadyYielded; BaseType_t xTimeoutOccurred = pdFALSE; /* Check the user is not attempting to wait on the bits used by the kernel * itself, and that at least one bit is being requested. */ configASSERT( xEventGroup ); configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); configASSERT( uxBitsToWaitFor != 0 ); #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) { configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); } #endif vTaskSuspendAll(); { const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits; /* Check to see if the wait condition is already met or not. */ xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits ); if( xWaitConditionMet != pdFALSE ) { /* The wait condition has already been met so there is no need to * block. */ uxReturn = uxCurrentEventBits; xTicksToWait = ( TickType_t ) 0; /* Clear the wait bits if requested to do so. */ if( xClearOnExit != pdFALSE ) { pxEventBits->uxEventBits &= ~uxBitsToWaitFor; } else { mtCOVERAGE_TEST_MARKER(); } } else if( xTicksToWait == ( TickType_t ) 0 ) { /* The wait condition has not been met, but no block time was * specified, so just return the current value. */ uxReturn = uxCurrentEventBits; xTimeoutOccurred = pdTRUE; } else { /* The task is going to block to wait for its required bits to be * set. uxControlBits are used to remember the specified behaviour of * this call to xEventGroupWaitBits() - for use when the event bits * unblock the task. */ if( xClearOnExit != pdFALSE ) { uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT; } else { mtCOVERAGE_TEST_MARKER(); } if( xWaitForAllBits != pdFALSE ) { uxControlBits |= eventWAIT_FOR_ALL_BITS; } else { mtCOVERAGE_TEST_MARKER(); } /* Store the bits that the calling task is waiting for in the * task's event list item so the kernel knows when a match is * found. Then enter the blocked state. */ vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait ); /* This is obsolete as it will get set after the task unblocks, but * some compilers mistakenly generate a warning about the variable * being returned without being set if it is not done. */ uxReturn = 0; traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ); } } xAlreadyYielded = xTaskResumeAll(); if( xTicksToWait != ( TickType_t ) 0 ) { if( xAlreadyYielded == pdFALSE ) { portYIELD_WITHIN_API(); } else { mtCOVERAGE_TEST_MARKER(); } /* The task blocked to wait for its required bits to be set - at this * point either the required bits were set or the block time expired. If * the required bits were set they will have been stored in the task's * event list item, and they should now be retrieved then cleared. */ uxReturn = uxTaskResetEventItemValue(); if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) { taskENTER_CRITICAL(); { /* The task timed out, just return the current event bit value. */ uxReturn = pxEventBits->uxEventBits; /* It is possible that the event bits were updated between this * task leaving the Blocked state and running again. */ if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE ) { if( xClearOnExit != pdFALSE ) { pxEventBits->uxEventBits &= ~uxBitsToWaitFor; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } xTimeoutOccurred = pdTRUE; } taskEXIT_CRITICAL(); } else { /* The task unblocked because the bits were set. */ } /* The task blocked so control bits may have been set. */ uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; } traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ); /* Prevent compiler warnings when trace macros are not used. */ ( void ) xTimeoutOccurred; return uxReturn; } /*-----------------------------------------------------------*/ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) { EventGroup_t * pxEventBits = xEventGroup; EventBits_t uxReturn; /* Check the user is not attempting to clear the bits used by the kernel * itself. */ configASSERT( xEventGroup ); configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); taskENTER_CRITICAL(); { traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ); /* The value returned is the event group value prior to the bits being * cleared. */ uxReturn = pxEventBits->uxEventBits; /* Clear the bits. */ pxEventBits->uxEventBits &= ~uxBitsToClear; } taskEXIT_CRITICAL(); return uxReturn; } /*-----------------------------------------------------------*/ #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) { BaseType_t xReturn; traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ); xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */ return xReturn; } #endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ /*-----------------------------------------------------------*/ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) { UBaseType_t uxSavedInterruptStatus; EventGroup_t const * const pxEventBits = xEventGroup; EventBits_t uxReturn; uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { uxReturn = pxEventBits->uxEventBits; } portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); return uxReturn; } /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */ /*-----------------------------------------------------------*/ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) { ListItem_t * pxListItem; ListItem_t * pxNext; ListItem_t const * pxListEnd; List_t const * pxList; EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits; EventGroup_t * pxEventBits = xEventGroup; BaseType_t xMatchFound = pdFALSE; /* Check the user is not attempting to set the bits used by the kernel * itself. */ configASSERT( xEventGroup ); configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); pxList = &( pxEventBits->xTasksWaitingForBits ); pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ vTaskSuspendAll(); { traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ); pxListItem = listGET_HEAD_ENTRY( pxList ); /* Set the bits. */ pxEventBits->uxEventBits |= uxBitsToSet; /* See if the new bit value should unblock any tasks. */ while( pxListItem != pxListEnd ) { pxNext = listGET_NEXT( pxListItem ); uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem ); xMatchFound = pdFALSE; /* Split the bits waited for from the control bits. */ uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES; uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES; if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 ) { /* Just looking for single bit being set. */ if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 ) { xMatchFound = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor ) { /* All bits are set. */ xMatchFound = pdTRUE; } else { /* Need all bits to be set, but not all the bits were set. */ } if( xMatchFound != pdFALSE ) { /* The bits match. Should the bits be cleared on exit? */ if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 ) { uxBitsToClear |= uxBitsWaitedFor; } else { mtCOVERAGE_TEST_MARKER(); } /* Store the actual event flag value in the task's event list * item before removing the task from the event list. The * eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows * that is was unblocked due to its required bits matching, rather * than because it timed out. */ vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET ); } /* Move onto the next list item. Note pxListItem->pxNext is not * used here as the list item may have been removed from the event list * and inserted into the ready/pending reading list. */ pxListItem = pxNext; } /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT * bit was set in the control word. */ pxEventBits->uxEventBits &= ~uxBitsToClear; } ( void ) xTaskResumeAll(); return pxEventBits->uxEventBits; } /*-----------------------------------------------------------*/ void vEventGroupDelete( EventGroupHandle_t xEventGroup ) { EventGroup_t * pxEventBits = xEventGroup; const List_t * pxTasksWaitingForBits; configASSERT( pxEventBits ); pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits ); vTaskSuspendAll(); { traceEVENT_GROUP_DELETE( xEventGroup ); while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 ) { /* Unblock the task, returning 0 as the event list is being deleted * and cannot therefore have any bits set. */ configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); } } ( void ) xTaskResumeAll(); #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) { /* The event group can only have been allocated dynamically - free * it again. */ vPortFree( pxEventBits ); } #elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) { /* The event group could have been allocated statically or * dynamically, so check before attempting to free the memory. */ if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) { vPortFree( pxEventBits ); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ } /*-----------------------------------------------------------*/ /* For internal use only - execute a 'set bits' command that was pended from * an interrupt. */ void vEventGroupSetBitsCallback( void * pvEventGroup, const uint32_t ulBitsToSet ) { ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ } /*-----------------------------------------------------------*/ /* For internal use only - execute a 'clear bits' command that was pended from * an interrupt. */ void vEventGroupClearBitsCallback( void * pvEventGroup, const uint32_t ulBitsToClear ) { ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ } /*-----------------------------------------------------------*/ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) { BaseType_t xWaitConditionMet = pdFALSE; if( xWaitForAllBits == pdFALSE ) { /* Task only has to wait for one bit within uxBitsToWaitFor to be * set. Is one already set? */ if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 ) { xWaitConditionMet = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else { /* Task has to wait for all the bits in uxBitsToWaitFor to be set. * Are they set already? */ if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor ) { xWaitConditionMet = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } return xWaitConditionMet; } /*-----------------------------------------------------------*/ #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t * pxHigherPriorityTaskWoken ) { BaseType_t xReturn; traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ); xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */ return xReturn; } #endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxEventGroupGetNumber( void * xEventGroup ) { UBaseType_t xReturn; EventGroup_t const * pxEventBits = ( EventGroup_t * ) xEventGroup; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ if( xEventGroup == NULL ) { xReturn = 0; } else { xReturn = pxEventBits->uxEventGroupNumber; } return xReturn; } #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ #if ( configUSE_TRACE_FACILITY == 1 ) void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) { ( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ } #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/examples/blinky/FreeRTOSConfig.h ================================================ /* Modified by Quantum Leaps */ /* * FreeRTOS V202212.00 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H /*----------------------------------------------------------- * Application specific definitions. * * These definitions should be adjusted for your particular hardware and * application requirements. * * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. * * See http://www.freertos.org/a00110.html *----------------------------------------------------------*/ #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 1 #define configUSE_TICK_HOOK 1 #define configCPU_CLOCK_HZ ( SystemCoreClock ) #define configTICK_RATE_HZ ( ( TickType_t )100 ) #define configMAX_PRIORITIES ( 32 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short )128 ) #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 0 ) ) #define configMAX_TASK_NAME_LEN ( 16 ) #define configUSE_TRACE_FACILITY 0 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 0 #define configUSE_MUTEXES 0 /* use only the static allocation */ #define configSUPPORT_DYNAMIC_ALLOCATION 0 #define configSUPPORT_STATIC_ALLOCATION 1 /* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskCleanUpResources 0 #define INCLUDE_vTaskSuspend 0 #define INCLUDE_vTaskDelayUntil 0 #define INCLUDE_vTaskDelay 1 /* This is the raw value as per the Cortex-M NVIC. Values can be 255 (lowest) to 0 (1?) (highest). */ #define configKERNEL_INTERRUPT_PRIORITY 255 /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 0xb0, or priority 11. */ /* This is the value being used as per the ST library which permits 16 priority values, 0 to 15. This must correspond to the configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest NVIC value of 255. */ #define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15 /* Prevent the inclusion of items the assembler will not understand in assembly files. */ #ifndef __IAR_SYSTEMS_ASM__ #define configASSERT( x ) if( ( x ) == 0 ) assert_failed( __FILE__, __LINE__ ); void assert_failed(char const * const module, int location); extern uint32_t SystemCoreClock; #endif /* Map the FreeRTOS port interrupt handlers to their CMSIS standard names. */ #define vPortSVCHandler SVC_Handler #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #endif /* FREERTOS_CONFIG_H */ ================================================ FILE: FreeRTOS-comparison/examples/blinky/armclang/nucleo-l053r8.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 nucleo-l053r8 0x4 ARM-ADS 12000000 1 1 0 1 0 1 65535 0 0 0 79 66 8 .\build_nucleo-l053r8\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 UL2CM3 UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM)) 0 ST-LINKIII-KEIL_SWO -U066CFF484951775087074312 -O8431 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P2 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC800 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=1702,853,2113,1355,0)(1007=2082,245,2289,466,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS 0 1 QUEUE_Blinky1 1 2 0xE000E400 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 10000000 Application 1 0 0 0 1 1 5 0 0 0 ..\FreeRTOSConfig.h FreeRTOSConfig.h 0 0 1 2 5 0 0 0 ..\bsp.h bsp.h 0 0 1 3 1 0 0 0 ..\main.c main.c 0 0 1 4 1 0 0 0 ..\bsp_nucleo-l053r8.c bsp_nucleo-l053r8.c 0 0 1 5 1 0 0 0 ..\blinky.c blinky.c 0 0 1 6 5 0 0 0 ..\blinky.h blinky.h 0 0 nucleo-l053r8 1 0 0 0 2 7 2 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s startup_stm32l053xx.s 0 0 2 8 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l0xx.h 0 0 2 9 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h stm32l053xx.h 0 0 2 10 1 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c system_stm32l0xx.c 0 0 FreeRTOS-Kernel 1 0 0 0 3 11 1 0 0 0 ..\..\..\list.c list.c 0 0 3 12 1 0 0 0 ..\..\..\queue.c queue.c 0 0 3 13 1 0 0 0 ..\..\..\tasks.c tasks.c 0 0 3 14 1 0 0 0 ..\..\..\portable\GCC\ARM_CM0\port.c port.c 0 0
================================================ FILE: FreeRTOS-comparison/examples/blinky/armclang/nucleo-l053r8.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
nucleo-l053r8 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32L053R8Tx STMicroelectronics Keil.STM32L0xx_DFP.2.2.0 http://www.keil.com/pack/ IRAM(0x20000000,0x00002000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$Flash\STM32L0xx_64.FLM)) 0 $$Device:STM32L053R8Tx$Device\Include\stm32l0xx.h $$Device:STM32L053R8Tx$SVD\STM32L053x.svd 0 0 0 0 0 0 1 .\build_nucleo-l053r8\ blinky_button 1 0 0 1 1 .\build_nucleo-l053r8\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-l053r8\blinky_button.bin .\build_nucleo-l053r8\blinky_button.axf 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP DARMCM1.DLL -pCM0+ SARMCM3.DLL TARMCM1.DLL -pCM0+ 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M0+" 0 0 0 1 1 0 0 0 0 0 0 0 8 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 1 0x8000000 0x10000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x10000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 0 0x0 0x0 0 0 0 0 1 0 0 0 0 0 4 0 1 0 0 0 3 3 0 0 0 0 0 -Wno-padded ..;..\..\..\include;..\..\..\portable\GCC\ARM_CM0;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-l053r8 1 0 0 0 0 0 0 1 0 4 Stack_Size=1024 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Application FreeRTOSConfig.h 5 ..\FreeRTOSConfig.h bsp.h 5 ..\bsp.h main.c 1 ..\main.c bsp_nucleo-l053r8.c 1 ..\bsp_nucleo-l053r8.c blinky.c 1 ..\blinky.c blinky.h 5 ..\blinky.h nucleo-l053r8 startup_stm32l053xx.s 2 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s stm32l0xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l053xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h system_stm32l0xx.c 1 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c FreeRTOS-Kernel list.c 1 ..\..\..\list.c queue.c 1 ..\..\..\queue.c tasks.c 1 ..\..\..\tasks.c port.c 1 ..\..\..\portable\GCC\ARM_CM0\port.c nucleo-l053r8 1
================================================ FILE: FreeRTOS-comparison/examples/blinky/blinky.c ================================================ /*============================================================================ * Blinky1 task (adapted for FreeRTOS) * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "FreeRTOS.h" /* FreeRTOS API */ #include "task.h" /* FreeRTOS task API */ #include "blinky.h" /* application shared interface */ #include "bsp.h" /* Board Support Package interface */ /*..........................................................................*/ void Blinky_task(void *pvParameters) { (void)pvParameters; /* unused parameter */ while (1) { BSP_ledOn(); vTaskDelay(BSP_TICKS_PER_SEC / 4U); BSP_ledOff(); vTaskDelay(BSP_TICKS_PER_SEC * 3U/4U); } } ================================================ FILE: FreeRTOS-comparison/examples/blinky/blinky.h ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #ifndef BLINKY_H_ #define BLINKY_H_ /*--------------------------------------------------------------------------*/ /* Tasks and event queues for this application... */ void Blinky_task(void *pvParameters); /* general convenience utilities -------------------------------------------*/ #ifndef ARRAY_NELEM /*! convenience macro to provide the number of elements in the array a_ */ #define ARRAY_NELEM(a_) (sizeof(a_) / sizeof((a_)[0])) #endif /* ARRAY_NELEM */ #endif /* BLINKY_BUTTON_H_ */ ================================================ FILE: FreeRTOS-comparison/examples/blinky/bsp.h ================================================ /*============================================================================ * FreeRTOS Example (adaptation of the SST blinky_button example) * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #ifndef BSP_H_ #define BSP_H_ #define BSP_TICKS_PER_SEC configTICK_RATE_HZ void BSP_init(void); void BSP_ledOn(void); void BSP_ledOff(void); #endif /* BSP_H_ */ ================================================ FILE: FreeRTOS-comparison/examples/blinky/bsp_nucleo-l053r8.c ================================================ /*============================================================================ * FreeRTOS Example (adaptation of the SST blinky_button example) * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "FreeRTOS.h" /* FreeRTOS API */ #include "task.h" /* FreeRTOS task API */ #include "queue.h" /* FreeRTOS queue API */ #include "blinky.h" #include "bsp.h" #include "stm32l0xx.h" /* CMSIS-compliant header file for the MCU used */ /* add other drivers if necessary... */ /* Local-scope defines -----------------------------------------------------*/ /* test pins on GPIO PA */ #define LED_PIN 5U /* LED LD2-Green */ /* Function Prototype ======================================================*/ void vApplicationTickHook(void); void vApplicationIdleHook(void); void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName); void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize); void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize); /* Hooks ===================================================================*/ /* Application hooks used in this project ==================================*/ /* NOTE: only the "FromISR" API variants are allowed in vApplicationTickHook*/ void vApplicationTickHook(void) { } /*..........................................................................*/ void vApplicationIdleHook(void) { #ifdef NDEBUG /* Put the CPU and peripherals to the low-power mode. * you might need to customize the clock management for your application, * see the datasheet for your particular Cortex-M3 MCU. */ __WFI(); /* Wait-For-Interrupt */ #endif } /*..........................................................................*/ void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) { (void)xTask; (void)pcTaskName; /* ERROR!!! */ } /*..........................................................................*/ /* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must * provide an implementation of vApplicationGetIdleTaskMemory() to provide * the memory that is used by the Idle task. */ void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) { /* If the buffers to be provided to the Idle task are declared inside * this function then they must be declared static - otherwise they will * be allocated on the stack and so not exists after this function exits. */ static StaticTask_t xIdleTaskTCB; static StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE]; /* Pass out a pointer to the StaticTask_t structure in which the * Idle task's state will be stored. */ *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; /* Pass out the array that will be used as the Idle task's stack. */ *ppxIdleTaskStackBuffer = &uxIdleTaskStack[0]; /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. * Note that, as the array is necessarily of type StackType_t, * configMINIMAL_STACK_SIZE is specified in words, not bytes. */ *pulIdleTaskStackSize = sizeof(uxIdleTaskStack) / sizeof(uxIdleTaskStack[0]); } /* BSP functions ===========================================================*/ void BSP_init(void) { /* Configure the MPU to prevent NULL-pointer dereferencing * see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu */ MPU->RBAR = 0x0U /* base address (NULL) */ | MPU_RBAR_VALID_Msk /* valid region */ | (MPU_RBAR_REGION_Msk & 7U); /* region #7 */ MPU->RASR = (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1) region */ | (0x0U << MPU_RASR_AP_Pos) /* no-access region */ | MPU_RASR_ENABLE_Msk; /* region enable */ MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk /* enable background region */ | MPU_CTRL_ENABLE_Msk; /* enable the MPU */ __ISB(); __DSB(); /* enable GPIO port PA clock */ RCC->IOPENR |= (1U << 0U); /* set all used GPIOA pins as push-pull output, no pull-up, pull-down */ GPIOA->MODER &= ~(3U << 2U*LED_PIN); GPIOA->MODER |= (1U << 2U*LED_PIN); GPIOA->OTYPER &= ~(1U << LED_PIN); GPIOA->PUPDR &= ~(3U << 2U*LED_PIN); } /*..........................................................................*/ void BSP_ledOn(void) { GPIOA->BSRR = (1U << LED_PIN); } /* LED2 */ void BSP_ledOff(void) { GPIOA->BSRR = (1U << (LED_PIN + 16U)); } /*..........................................................................*/ void BSP_start(void) { SystemCoreClockUpdate(); /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ SysTick_Config((SystemCoreClock / BSP_TICKS_PER_SEC) + 1U); /* set priorities of ISRs used in the system */ NVIC_SetPriority(SysTick_IRQn, 0U); /* ... */ } /* Assertion handler ======================================================*/ void assert_failed(char const * const module, int const label);/* prototype */ void assert_failed(char const * const module, int const label) { /* * NOTE: add here your application-specific error handling */ (void)module; (void)label; /* set PRIMASK to disable interrupts and stop right here */ __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { /* keep blinking LED2 */ BSP_ledOn(); /* turn LED2 on */ uint32_t volatile ctr; for (ctr = 10000U; ctr > 0U; --ctr) { } BSP_ledOff(); /* turn LED2 off */ for (ctr = 10000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } /***************************************************************************** * NOTE1: * Only ISRs prioritized at or below the * configMAX_SYSCALL_INTERRUPT_PRIORITY level (i.e., * with the numerical values of priorities equal or higher than * configMAX_SYSCALL_INTERRUPT_PRIORITY) are allowed to call any * QP/FreeRTOS services. These ISRs are "kernel-aware". * * Only ISRs prioritized at or below the configMAX_SYSCALL_INTERRUPT_PRIORITY * level (i.e., with the numerical values of priorities equal or higher than * configMAX_SYSCALL_INTERRUPT_PRIORITY) are allowed to call any QF services. * These ISRs are "kernel-aware". * * Conversely, any ISRs prioritized above the * configMAX_SYSCALL_INTERRUPT_PRIORITY priority level (i.e., with * the numerical values of priorities less than * configMAX_SYSCALL_INTERRUPT_PRIORITY) are never disabled and are * not aware of the kernel. Such "kernel-unaware" ISRs cannot call any * QP/FreeRTOS services. The only mechanism by which a "kernel-unaware" ISR * can communicate with the QF framework is by triggering a "kernel-aware" * ISR, which can post/publish events. * * For more information, see article "Running the RTOS on a ARM Cortex-M Core" * http://www.freertos.org/RTOS-Cortex-M3-M4.html */ ================================================ FILE: FreeRTOS-comparison/examples/blinky/main.c ================================================ /*============================================================================ * FreeRTOS Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "FreeRTOS.h" /* FreeRTOS API */ #include "task.h" /* FreeRTOS task API */ #include "blinky.h" /* application shared interface */ #include "bsp.h" /* Board Support Package interface */ /*..........................................................................*/ int main() { BSP_init(); /* initialize the Board Support Package */ /* instantiate and start all FreeRTOS tasks... */ TaskHandle_t th; /* Blinky... */ static StaticTask_t Blinky_tcb; /* task control block */ static StackType_t Blinky_stack[configMINIMAL_STACK_SIZE]; th = xTaskCreateStatic( &Blinky_task, /* task function */ "Blinky", /* task priority */ ARRAY_NELEM(Blinky_stack), /* stack length */ (void *)0, /* task param (not used) */ 1U + tskIDLE_PRIORITY, /* task priority */ Blinky_stack, /* task stack */ &Blinky_tcb); /* task control block */ configASSERT(th); /* task creation must succeed */ vTaskStartScheduler(); /* start the FreeRTOS scheduler... */ return 0; /* NOTE: the scheduler does NOT return */ } ================================================ FILE: FreeRTOS-comparison/examples/blinky_button/FreeRTOSConfig.h ================================================ /* Modified by Quantum Leaps */ /* * FreeRTOS V202212.00 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H /*----------------------------------------------------------- * Application specific definitions. * * These definitions should be adjusted for your particular hardware and * application requirements. * * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. * * See http://www.freertos.org/a00110.html *----------------------------------------------------------*/ #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 1 #define configUSE_TICK_HOOK 1 #define configCPU_CLOCK_HZ ( SystemCoreClock ) #define configTICK_RATE_HZ ( ( TickType_t )100 ) #define configMAX_PRIORITIES ( 32 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short )128 ) #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 0 ) ) #define configMAX_TASK_NAME_LEN ( 16 ) #define configUSE_TRACE_FACILITY 0 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 0 #define configUSE_MUTEXES 0 /* use only the static allocation */ #define configSUPPORT_DYNAMIC_ALLOCATION 0 #define configSUPPORT_STATIC_ALLOCATION 1 /* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskCleanUpResources 0 #define INCLUDE_vTaskSuspend 0 #define INCLUDE_vTaskDelayUntil 0 #define INCLUDE_vTaskDelay 1 /* This is the raw value as per the Cortex-M NVIC. Values can be 255 (lowest) to 0 (1?) (highest). */ #define configKERNEL_INTERRUPT_PRIORITY 255 /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 0xb0, or priority 11. */ /* This is the value being used as per the ST library which permits 16 priority values, 0 to 15. This must correspond to the configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest NVIC value of 255. */ #define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15 /* Prevent the inclusion of items the assembler will not understand in assembly files. */ #ifndef __IAR_SYSTEMS_ASM__ #define configASSERT( x ) if( ( x ) == 0 ) assert_failed( __FILE__, __LINE__ ); void assert_failed(char const * const module, int location); extern uint32_t SystemCoreClock; #endif /* Map the FreeRTOS port interrupt handlers to their CMSIS standard names. */ #define vPortSVCHandler SVC_Handler #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #endif /* FREERTOS_CONFIG_H */ ================================================ FILE: FreeRTOS-comparison/examples/blinky_button/armclang/nucleo-l053r8.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 nucleo-l053r8 0x4 ARM-ADS 12000000 1 1 0 1 0 1 65535 0 0 0 79 66 8 .\build_nucleo-l053r8\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 UL2CM3 UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM)) 0 ST-LINKIII-KEIL_SWO -U066CFF484951775087074312 -O8431 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P2 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC800 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=1702,853,2113,1355,0)(1007=2082,245,2289,466,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS 0 0 51 1
134219654
0 0 0 0 0 1 ..\blinky1.c \\blinky_button\../blinky1.c\51
0 1 QUEUE_Blinky1 1 2 0xE000E400 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 10000000
Application 1 0 0 0 1 1 5 0 0 0 ..\FreeRTOSConfig.h FreeRTOSConfig.h 0 0 1 2 5 0 0 0 ..\blinky_button.h blinky_button.h 0 0 1 3 5 0 0 0 ..\bsp.h bsp.h 0 0 1 4 1 0 0 0 ..\main.c main.c 0 0 1 5 1 0 0 0 ..\bsp_nucleo-l053r8.c bsp_nucleo-l053r8.c 0 0 1 6 1 0 0 0 ..\blinky1.c blinky1.c 0 0 1 7 1 0 0 0 ..\blinky3.c blinky3.c 0 0 1 8 1 0 0 0 ..\button2a.c button2a.c 0 0 1 9 1 0 0 0 ..\button2b.c button2b.c 0 0 nucleo-l053r8 1 0 0 0 2 10 2 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s startup_stm32l053xx.s 0 0 2 11 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l0xx.h 0 0 2 12 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h stm32l053xx.h 0 0 2 13 1 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c system_stm32l0xx.c 0 0 FreeRTOS-Kernel 1 0 0 0 3 14 1 0 0 0 ..\..\..\list.c list.c 0 0 3 15 1 0 0 0 ..\..\..\queue.c queue.c 0 0 3 16 1 0 0 0 ..\..\..\tasks.c tasks.c 0 0 3 17 1 0 0 0 ..\..\..\portable\GCC\ARM_CM0\port.c port.c 0 0
================================================ FILE: FreeRTOS-comparison/examples/blinky_button/armclang/nucleo-l053r8.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
nucleo-l053r8 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32L053R8Tx STMicroelectronics Keil.STM32L0xx_DFP.2.2.0 http://www.keil.com/pack/ IRAM(0x20000000,0x00002000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$Flash\STM32L0xx_64.FLM)) 0 $$Device:STM32L053R8Tx$Device\Include\stm32l0xx.h $$Device:STM32L053R8Tx$SVD\STM32L053x.svd 0 0 0 0 0 0 1 .\build_nucleo-l053r8\ blinky_button 1 0 0 1 1 .\build_nucleo-l053r8\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-l053r8\blinky_button.bin .\build_nucleo-l053r8\blinky_button.axf 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP DARMCM1.DLL -pCM0+ SARMCM3.DLL TARMCM1.DLL -pCM0+ 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M0+" 0 0 0 1 1 0 0 0 0 0 0 0 8 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 1 0x8000000 0x10000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x10000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 0 0x0 0x0 0 5 0 0 1 0 0 0 0 0 4 0 1 0 0 0 3 3 0 0 0 0 0 -Wno-padded ..;..\..\..\include;..\..\..\portable\GCC\ARM_CM0;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-l053r8 1 0 0 0 0 0 0 1 0 4 Stack_Size=1024 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Application FreeRTOSConfig.h 5 ..\FreeRTOSConfig.h blinky_button.h 5 ..\blinky_button.h bsp.h 5 ..\bsp.h main.c 1 ..\main.c bsp_nucleo-l053r8.c 1 ..\bsp_nucleo-l053r8.c blinky1.c 1 ..\blinky1.c blinky3.c 1 ..\blinky3.c button2a.c 1 ..\button2a.c button2b.c 1 ..\button2b.c nucleo-l053r8 startup_stm32l053xx.s 2 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s stm32l0xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l053xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h system_stm32l0xx.c 1 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c FreeRTOS-Kernel list.c 1 ..\..\..\list.c queue.c 1 ..\..\..\queue.c tasks.c 1 ..\..\..\tasks.c port.c 1 ..\..\..\portable\GCC\ARM_CM0\port.c nucleo-l053r8 1
================================================ FILE: FreeRTOS-comparison/examples/blinky_button/blinky1.c ================================================ /*============================================================================ * Blinky1 task (adapted for FreeRTOS) * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "FreeRTOS.h" /* FreeRTOS API */ #include "task.h" /* FreeRTOS task API */ #include "queue.h" /* FreeRTOS queue API */ #include "blinky_button.h" /* application shared interface */ #include "bsp.h" /* Board Support Package interface */ /*..........................................................................*/ typedef struct { /* Blinky1 private data */ uint16_t toggles; uint8_t ticks; uint8_t tick_ctr; } Blinky1; static void Blinky1_init(Blinky1 * const me, Event const * const ie); static void Blinky1_dispatch(Blinky1 * const me, Event const * const e); static Blinky1 Blinky1_inst; /* the Blinky1 instance (Singleton) */ /*..........................................................................*/ void * const AO_Blinky1 = &Blinky1_inst; /* opaque AO pointer */ QueueHandle_t QUEUE_Blinky1; /* FreeRTOS queue "handle" */ /*..........................................................................*/ void Blinky1_task(void *pvParameters) { Blinky1 * const me = (Blinky1 *)pvParameters; Blinky1_init(me, BSP_getWorkEvtBlinky1(0U)); while (1) { /* wait for any event and receive it into object 'e' */ Event *e; xQueueReceive(QUEUE_Blinky1, &e, portMAX_DELAY); /* BLOCKING! */ configASSERT(e != (Event *)0); Blinky1_dispatch(me, e); } } /*..........................................................................*/ static void Blinky1_init(Blinky1 * const me, Event const * const ie) { /* the initial event must be provided and must be WORKLOAD_SIG */ configPRECONDITION((ie != (Event const *)0) && (ie->sig == BLINKY_WORK_SIG)); me->toggles = EVT_DOWNCAST(BlinkyWorkEvt, ie)->toggles; me->ticks = EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks; me->tick_ctr = me->ticks; } /*..........................................................................*/ static void Blinky1_dispatch(Blinky1 * const me, Event const * const e) { switch (e->sig) { case TICK_SIG: { --me->tick_ctr; if (me->tick_ctr == 0U) { me->tick_ctr = me->ticks; for (uint16_t i = me->toggles; i > 0U; --i) { BSP_d5on(); BSP_d5off(); } } break; } case BLINKY_WORK_SIG: { BSP_d5on(); me->toggles = EVT_DOWNCAST(BlinkyWorkEvt, e)->toggles; me->ticks = EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks; BSP_d5off(); break; } default: { configASSERT(0); /* unexpected event */ break; } } } ================================================ FILE: FreeRTOS-comparison/examples/blinky_button/blinky3.c ================================================ /*============================================================================ * Blinky3 task (adapted for FreeRTOS) * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "FreeRTOS.h" /* FreeRTOS API */ #include "task.h" /* FreeRTOS task API */ #include "queue.h" /* FreeRTOS queue API */ #include "blinky_button.h" /* application shared interface */ #include "bsp.h" /* Board Support Package interface */ /*..........................................................................*/ typedef struct { /* Blinky3 task */ uint16_t toggles; uint8_t ticks; uint8_t tick_ctr; } Blinky3; static void Blinky3_init(Blinky3 * const me, Event const * const ie); static void Blinky3_dispatch(Blinky3 * const me, Event const * const e); static Blinky3 Blinky3_inst; /* the Blinky3 instance (Singleton) */ /*..........................................................................*/ void * const AO_Blinky3 = &Blinky3_inst; /* opaque AO pointer */ QueueHandle_t QUEUE_Blinky3; /* FreeRTOS queue "handle" */ /*..........................................................................*/ void Blinky3_task(void *pvParameters) { Blinky3 * const me = (Blinky3 *)pvParameters; Blinky3_init(me, BSP_getWorkEvtBlinky3(0U)); while (1) { /* wait for any event and receive it into object 'e' */ Event *e; xQueueReceive(QUEUE_Blinky3, &e, portMAX_DELAY); /* BLOCKING! */ configASSERT(e != (Event *)0); Blinky3_dispatch(me, e); } } /*..........................................................................*/ static void Blinky3_init(Blinky3 * const me, Event const * const ie) { /* the initial event must be provided and must be WORKLOAD_SIG */ configPRECONDITION((ie != (Event const *)0) && (ie->sig == BLINKY_WORK_SIG)); me->toggles = EVT_DOWNCAST(BlinkyWorkEvt, ie)->toggles; me->ticks = EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks; me->tick_ctr = me->ticks; } /*..........................................................................*/ static void Blinky3_dispatch(Blinky3 * const me, Event const * const e) { switch (e->sig) { case TICK_SIG: { --me->tick_ctr; if (me->tick_ctr == 0U) { me->tick_ctr = me->ticks; for (uint16_t i = me->toggles; i > 0U; --i) { BSP_d2on(); BSP_d2off(); } } break; } case BLINKY_WORK_SIG: { BSP_d2on(); me->toggles = EVT_DOWNCAST(BlinkyWorkEvt, e)->toggles; me->ticks = EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks; BSP_d2off(); break; } default: { configASSERT(0); /* unexpected event */ break; } } } ================================================ FILE: FreeRTOS-comparison/examples/blinky_button/blinky_button.h ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #ifndef BLINKY_BUTTON_H_ #define BLINKY_BUTTON_H_ /*--------------------------------------------------------------------------*/ /* Event facilities... */ /*! Event signal */ typedef uint16_t Signal; /*! Event class */ typedef struct { Signal sig; } Event; /*! macro for downcasting Events to specific Event "subclasses" */ #define EVT_DOWNCAST(EVT_, e_) ((EVT_ const *)(e_)) /*--------------------------------------------------------------------------*/ /* Custom Events for this application... */ enum Signals { TICK_SIG, BUTTON_PRESSED_SIG, BUTTON_RELEASED_SIG, BLINKY_WORK_SIG, FORWARD_PRESSED_SIG, FORWARD_RELEASED_SIG, /* ... */ MAX_SIG /* the last signal */ }; typedef struct { Event super; /* inherit Event */ uint16_t toggles; /* number of toggles of the signal */ uint8_t ticks; /* number of clock ticks between */ } BlinkyWorkEvt; typedef struct { Event super; /* inherit Event */ uint16_t toggles; /* number of toggles of the signal */ } ButtonWorkEvt; /*--------------------------------------------------------------------------*/ /* Tasks and event queues for this application... */ void Blinky1_task(void *pvParameters); extern void * const AO_Blinky1; /* opaque task pointer */ extern QueueHandle_t QUEUE_Blinky1; /* queue handle */ void Blinky3_task(void *pvParameters); extern void * const AO_Blinky3; /* opaque task pointer */ extern QueueHandle_t QUEUE_Blinky3; /* queue handle */ void Button2a_task(void *pvParameters); extern void * const AO_Button2a; /* opaque task pointer */ extern QueueHandle_t QUEUE_Button2a; /* queue handle */ void Button2b_task(void *pvParameters); extern void * const AO_Button2b; /* opaque task pointer */ extern QueueHandle_t QUEUE_Button2b; /* queue handle */ /* general convenience utilities -------------------------------------------*/ #ifndef ARRAY_NELEM /*! convenience macro to provide the number of elements in the array a_ */ #define ARRAY_NELEM(a_) (sizeof(a_) / sizeof((a_)[0])) #endif /* ARRAY_NELEM */ #endif /* BLINKY_BUTTON_H_ */ ================================================ FILE: FreeRTOS-comparison/examples/blinky_button/bsp.h ================================================ /*============================================================================ * FreeRTOS Example (adaptation of the SST blinky_button example) * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #ifndef BSP_H_ #define BSP_H_ #define BSP_TICKS_PER_SEC configTICK_RATE_HZ void BSP_init(void); void BSP_d1on(void); void BSP_d1off(void); void BSP_d2on(void); void BSP_d2off(void); void BSP_d3on(void); void BSP_d3off(void); void BSP_d4on(void); void BSP_d4off(void); void BSP_d5on(void); void BSP_d5off(void); void BSP_d6on(void); void BSP_d6off(void); /* immutable events for Blinky tasks */ Event const *BSP_getWorkEvtBlinky1(uint8_t num); Event const *BSP_getWorkEvtBlinky3(uint8_t num); #endif /* BSP_H_ */ ================================================ FILE: FreeRTOS-comparison/examples/blinky_button/bsp_nucleo-l053r8.c ================================================ /*============================================================================ * FreeRTOS Example (adaptation of the SST blinky_button example) * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "FreeRTOS.h" /* FreeRTOS API */ #include "task.h" /* FreeRTOS task API */ #include "queue.h" /* FreeRTOS queue API */ #include "blinky_button.h" #include "bsp.h" #include "stm32l0xx.h" /* CMSIS-compliant header file for the MCU used */ /* add other drivers if necessary... */ /* Local-scope defines -----------------------------------------------------*/ /* test pins on GPIO PA */ #define TST1_PIN 7U #define TST2_PIN 6U #define TST3_PIN 4U #define TST4_PIN 1U #define TST5_PIN 0U #define TST6_PIN 5U /* LED LD2-Green */ /* buttons on GPIO PC */ #define B1_PIN 13U /* Function Prototype ======================================================*/ void vApplicationTickHook(void); void vApplicationIdleHook(void); void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName); void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize); void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize); /* Hooks ===================================================================*/ /* Application hooks used in this project ==================================*/ /* NOTE: only the "FromISR" API variants are allowed in vApplicationTickHook*/ void vApplicationTickHook(void) { BSP_d1on(); BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t qStatus; /* immutable timeout event */ static Event const tickEvt = { TICK_SIG }; static Event const * const p_tickEvt = &tickEvt; qStatus = xQueueSendFromISR(QUEUE_Blinky1, (void const *)&p_tickEvt, &xHigherPriorityTaskWoken); configASSERT(qStatus == pdTRUE); qStatus = xQueueSendFromISR(QUEUE_Blinky3, (void const *)&p_tickEvt, &xHigherPriorityTaskWoken); configASSERT(qStatus == pdTRUE); /* Perform the debouncing of buttons. The algorithm for debouncing * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle * and Michael Barr, page 71. */ static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = ~GPIOC->IDR; /* read GPIO PortC */ uint32_t tmp = buttons.depressed; /* save the debounced depressed */ buttons.depressed |= (buttons.previous & current); /* set depressed */ buttons.depressed &= (buttons.previous | current); /* clear released */ buttons.previous = current; /* update the history */ tmp ^= buttons.depressed; /* changed debounced depressed */ if ((tmp & (1U << B1_PIN)) != 0U) { /* debounced B1 state changed? */ if ((buttons.depressed & (1U << B1_PIN)) != 0U) { /* depressed? */ /* immutable button-press event */ static ButtonWorkEvt const pressEvt = { .super.sig = BUTTON_PRESSED_SIG, .toggles = 60U }; static Event const * const p_pressEvt = &pressEvt.super; /* immutable forward-press event */ static ButtonWorkEvt const fPressEvt = { .super.sig = FORWARD_PRESSED_SIG, .toggles = 60U }; static Event const * const p_fPressEvt = &fPressEvt.super; qStatus = xQueueSendFromISR(QUEUE_Button2a, (void const *)&p_fPressEvt, &xHigherPriorityTaskWoken); configASSERT(qStatus == pdTRUE); qStatus = xQueueSendFromISR(QUEUE_Button2a, (void const *)&p_pressEvt, &xHigherPriorityTaskWoken); configASSERT(qStatus == pdTRUE); } else { /* B1 is released */ /* immutable button-release event */ static ButtonWorkEvt const releaseEvt = { .super.sig = BUTTON_RELEASED_SIG, .toggles = 80U }; static Event const * const p_releaseEvt = &releaseEvt.super; /* immutable forward-release event */ static ButtonWorkEvt const fReleaseEvt = { .super.sig = FORWARD_RELEASED_SIG, .toggles = 80U }; static Event const * const p_fReleaseEvt = &fReleaseEvt.super; qStatus = xQueueSendFromISR(QUEUE_Button2a, (void *)&p_fReleaseEvt, &xHigherPriorityTaskWoken); configASSERT(qStatus == pdTRUE); qStatus = xQueueSendFromISR(QUEUE_Button2a, (void *)&p_releaseEvt, &xHigherPriorityTaskWoken); configASSERT(qStatus == pdTRUE); } } /* notify FreeRTOS to perform context switch from ISR, if needed */ portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); BSP_d1off(); } /*..........................................................................*/ void vApplicationIdleHook(void) { BSP_d6on(); /* turn LED2 on */ #ifdef NDEBUG /* Put the CPU and peripherals to the low-power mode. * you might need to customize the clock management for your application, * see the datasheet for your particular Cortex-M3 MCU. */ BSP_d6off(); /* turn LED2 off */ __WFI(); /* Wait-For-Interrupt */ BSP_d6on(); /* turn LED2 on */ #endif BSP_d6off(); /* turn LED2 off */ } /*..........................................................................*/ void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) { (void)xTask; (void)pcTaskName; /* ERROR!!! */ } /*..........................................................................*/ /* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must * provide an implementation of vApplicationGetIdleTaskMemory() to provide * the memory that is used by the Idle task. */ void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) { /* If the buffers to be provided to the Idle task are declared inside * this function then they must be declared static - otherwise they will * be allocated on the stack and so not exists after this function exits. */ static StaticTask_t xIdleTaskTCB; static StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE]; /* Pass out a pointer to the StaticTask_t structure in which the * Idle task's state will be stored. */ *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; /* Pass out the array that will be used as the Idle task's stack. */ *ppxIdleTaskStackBuffer = &uxIdleTaskStack[0]; /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. * Note that, as the array is necessarily of type StackType_t, * configMINIMAL_STACK_SIZE is specified in words, not bytes. */ *pulIdleTaskStackSize = sizeof(uxIdleTaskStack) / sizeof(uxIdleTaskStack[0]); } /* BSP functions ===========================================================*/ void BSP_init(void) { /* Configure the MPU to prevent NULL-pointer dereferencing * see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu */ MPU->RBAR = 0x0U /* base address (NULL) */ | MPU_RBAR_VALID_Msk /* valid region */ | (MPU_RBAR_REGION_Msk & 7U); /* region #7 */ MPU->RASR = (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1) region */ | (0x0U << MPU_RASR_AP_Pos) /* no-access region */ | MPU_RASR_ENABLE_Msk; /* region enable */ MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk /* enable background region */ | MPU_CTRL_ENABLE_Msk; /* enable the MPU */ __ISB(); __DSB(); /* enable GPIO port PA clock */ RCC->IOPENR |= (1U << 0U); /* set all used GPIOA pins as push-pull output, no pull-up, pull-down */ GPIOA->MODER &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); GPIOA->MODER |= ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); GPIOA->OTYPER &= ~((1U << TST1_PIN) | (1U << TST2_PIN) | (1U << TST3_PIN) | (1U << TST4_PIN) | (1U << TST5_PIN) | (1U << TST6_PIN)); GPIOA->PUPDR &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); /* enable GPIOC clock port for the Button B1 */ RCC->IOPENR |= (1U << 2U); /* configure Button B1 pin on GPIOC as input, no pull-up, pull-down */ GPIOC->MODER &= ~(3U << 2U*B1_PIN); GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); } /*..........................................................................*/ void BSP_d1on(void) { GPIOA->BSRR = (1U << TST1_PIN); } void BSP_d1off(void) { GPIOA->BSRR = (1U << (TST1_PIN + 16U)); } /*..........................................................................*/ void BSP_d2on(void) { GPIOA->BSRR = (1U << TST2_PIN); } void BSP_d2off(void) { GPIOA->BSRR = (1U << (TST2_PIN + 16U)); } /*..........................................................................*/ void BSP_d3on(void) { GPIOA->BSRR = (1U << TST3_PIN); } void BSP_d3off(void) { GPIOA->BSRR = (1U << (TST3_PIN + 16U)); } /*..........................................................................*/ void BSP_d4on(void) { GPIOA->BSRR = (1U << TST4_PIN); } void BSP_d4off(void) { GPIOA->BSRR = (1U << (TST4_PIN + 16U)); } /*..........................................................................*/ void BSP_d5on(void) { GPIOA->BSRR = (1U << TST5_PIN); } void BSP_d5off(void) { GPIOA->BSRR = (1U << (TST5_PIN + 16U)); } /*..........................................................................*/ void BSP_d6on(void) { GPIOA->BSRR = (1U << TST6_PIN); } /* LED2 */ void BSP_d6off(void) { GPIOA->BSRR = (1U << (TST6_PIN + 16U)); } /*..........................................................................*/ Event const *BSP_getWorkEvtBlinky1(uint8_t num) { /* immutable work events for Blinky1 */ static BlinkyWorkEvt const workBlinky1[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 40U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 30U, .ticks = 7U, } }; /* must be in range */ configPRECONDITION(num < sizeof(workBlinky1)/sizeof(workBlinky1[0])); return &workBlinky1[num].super; } /*..........................................................................*/ Event const *BSP_getWorkEvtBlinky3(uint8_t num) { /* immutable work events for Blinky3 */ static BlinkyWorkEvt const workBlinky3[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 20U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 10U, .ticks = 3U, } }; /* must be in range */ configPRECONDITION(num < sizeof(workBlinky3)/sizeof(workBlinky3[0])); return &workBlinky3[num].super; } /*..........................................................................*/ void BSP_start(void) { SystemCoreClockUpdate(); /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ SysTick_Config((SystemCoreClock / BSP_TICKS_PER_SEC) + 1U); /* set priorities of ISRs used in the system */ NVIC_SetPriority(SysTick_IRQn, 0U); /* ... */ } /* Assertion handler ======================================================*/ void assert_failed(char const * const module, int const label);/* prototype */ void assert_failed(char const * const module, int const label) { /* * NOTE: add here your application-specific error handling */ (void)module; (void)label; /* set PRIMASK to disable interrupts and stop right here */ __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { /* keep blinking LED2 */ BSP_d6on(); /* turn LED2 on */ uint32_t volatile ctr; for (ctr = 10000U; ctr > 0U; --ctr) { } BSP_d6off(); /* turn LED2 off */ for (ctr = 10000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } /***************************************************************************** * NOTE1: * Only ISRs prioritized at or below the * configMAX_SYSCALL_INTERRUPT_PRIORITY level (i.e., * with the numerical values of priorities equal or higher than * configMAX_SYSCALL_INTERRUPT_PRIORITY) are allowed to call any * QP/FreeRTOS services. These ISRs are "kernel-aware". * * Only ISRs prioritized at or below the configMAX_SYSCALL_INTERRUPT_PRIORITY * level (i.e., with the numerical values of priorities equal or higher than * configMAX_SYSCALL_INTERRUPT_PRIORITY) are allowed to call any QF services. * These ISRs are "kernel-aware". * * Conversely, any ISRs prioritized above the * configMAX_SYSCALL_INTERRUPT_PRIORITY priority level (i.e., with * the numerical values of priorities less than * configMAX_SYSCALL_INTERRUPT_PRIORITY) are never disabled and are * not aware of the kernel. Such "kernel-unaware" ISRs cannot call any * QP/FreeRTOS services. The only mechanism by which a "kernel-unaware" ISR * can communicate with the QF framework is by triggering a "kernel-aware" * ISR, which can post/publish events. * * For more information, see article "Running the RTOS on a ARM Cortex-M Core" * http://www.freertos.org/RTOS-Cortex-M3-M4.html */ ================================================ FILE: FreeRTOS-comparison/examples/blinky_button/button2a.c ================================================ /*============================================================================ * Button2a task (adapted for FreeRTOS) * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "FreeRTOS.h" /* FreeRTOS API */ #include "task.h" /* FreeRTOS task API */ #include "queue.h" /* FreeRTOS queue API */ #include "blinky_button.h" /* application shared interface */ #include "bsp.h" /* Board Support Package interface */ /*..........................................................................*/ typedef struct { /* Button2a task */ /* add internal variables for this AO... */ } Button2a; static void Button2a_init(Button2a * const me, Event const * const ie); static void Button2a_dispatch(Button2a * const me, Event const * const e); static Button2a Button2a_inst; /* the Button2a instance (Singleton) */ /*..........................................................................*/ void * const AO_Button2a = &Button2a_inst; /* opaque AO pointer */ QueueHandle_t QUEUE_Button2a; /* FreeRTOS queue "handle" */ /*..........................................................................*/ void Button2a_task(void *pvParameters) { Button2a * const me = (Button2a *)pvParameters; Button2a_init(me, (Event const *)0); while (1) { /* wait for any event and receive it into object 'e' */ Event *e; xQueueReceive(QUEUE_Button2a, &e, portMAX_DELAY); /* BLOCKING! */ configASSERT(e != (Event *)0); Button2a_dispatch(me, e); } } /*..........................................................................*/ static void Button2a_init(Button2a * const me, Event const * const ie) { (void)me; (void)ie; } /*..........................................................................*/ static void Button2a_dispatch(Button2a * const me, Event const * const e) { (void)me; BaseType_t qStatus; Event const *pe; switch (e->sig) { case BUTTON_PRESSED_SIG: { BSP_d4on(); /* Button2a --> Blinky1 */ pe = BSP_getWorkEvtBlinky1(1U); qStatus = xQueueSend(QUEUE_Blinky1, (void const *)&pe, (TickType_t)0); configASSERT(qStatus == pdTRUE); BSP_d4off(); for (uint16_t i = EVT_DOWNCAST(ButtonWorkEvt, e)->toggles; i > 0U; --i) { BSP_d4on(); BSP_d4off(); } break; } case FORWARD_PRESSED_SIG: { BSP_d4on(); /* immutable event can be forwarded to another Task */ /* Button2a --> Button2b */ qStatus = xQueueSend(QUEUE_Button2b, (void const *)&e, (TickType_t)0); configASSERT(qStatus == pdTRUE); BSP_d4off(); break; } case BUTTON_RELEASED_SIG: { BSP_d4on(); /* Button2a --> Blinky1 */ pe = BSP_getWorkEvtBlinky1(0U); qStatus = xQueueSend(QUEUE_Blinky1, (void const *)&pe, (TickType_t)0); configASSERT(qStatus == pdTRUE); BSP_d4off(); for (uint16_t i = EVT_DOWNCAST(ButtonWorkEvt, e)->toggles; i > 0U; --i) { BSP_d4on(); BSP_d4off(); } break; } case FORWARD_RELEASED_SIG: { BSP_d4on(); /* immutable event can be forwarded to another Task */ /* Button2a --> Button2b */ qStatus = xQueueSend(QUEUE_Button2b, (void const *)&e, (TickType_t)0); configASSERT(qStatus == pdTRUE); BSP_d4off(); break; } default: { configASSERT(0); /* unexpected event */ break; } } } ================================================ FILE: FreeRTOS-comparison/examples/blinky_button/button2b.c ================================================ /*============================================================================ * Button2b task (adapted for FreeRTOS) * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "FreeRTOS.h" /* FreeRTOS API */ #include "task.h" /* FreeRTOS task API */ #include "queue.h" /* FreeRTOS queue API */ #include "blinky_button.h" /* application shared interface */ #include "bsp.h" /* Board Support Package interface */ /*..........................................................................*/ typedef struct { /* Button2b task */ /* add internal variables for this AO... */ } Button2b; static void Button2b_init(Button2b * const me, Event const * const e); static void Button2b_dispatch(Button2b * const me, Event const * const e); static Button2b Button2b_inst; /* the Button2b instance */ /*..........................................................................*/ void * const AO_Button2b = &Button2b_inst; /* opaque AO pointer */ QueueHandle_t QUEUE_Button2b; /* FreeRTOS queue "handle" */ /*..........................................................................*/ void Button2b_task(void *pvParameters) { Button2b * const me = (Button2b *)pvParameters; Button2b_init(me, (Event const *)0); while (1) { /* wait for any event and receive it into object 'e' */ Event *e; xQueueReceive(QUEUE_Button2b, &e, portMAX_DELAY); /* BLOCKING! */ Button2b_dispatch(me, e); } } /*..........................................................................*/ static void Button2b_init(Button2b * const me, Event const * const ie) { (void)me; (void)ie; } /*..........................................................................*/ static void Button2b_dispatch(Button2b * const me, Event const * const e) { BaseType_t qStatus; Event const *pe; switch (e->sig) { case FORWARD_PRESSED_SIG: { BSP_d3on(); /* Button2b --> Blinky3 */ pe = BSP_getWorkEvtBlinky3(1U); qStatus = xQueueSend(QUEUE_Blinky3, (void const *)&pe, (TickType_t)0); configASSERT(qStatus == pdTRUE); BSP_d3off(); for (uint16_t i = EVT_DOWNCAST(ButtonWorkEvt, e)->toggles; i > 0U; --i) { BSP_d3on(); BSP_d3off(); } break; } case FORWARD_RELEASED_SIG: { BSP_d3on(); /* Button2b --> Blinky3 */ pe = BSP_getWorkEvtBlinky3(0U); qStatus = xQueueSend(QUEUE_Blinky3, (void const *)&pe, (TickType_t)0); configASSERT(qStatus == pdTRUE); BSP_d3off(); for (uint16_t i = EVT_DOWNCAST(ButtonWorkEvt, e)->toggles; i > 0U; --i) { BSP_d3on(); BSP_d3off(); } break; } default: { configASSERT(0); /* unexpected event */ break; } } } ================================================ FILE: FreeRTOS-comparison/examples/blinky_button/main.c ================================================ /*============================================================================ * FreeRTOS Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "FreeRTOS.h" /* FreeRTOS API */ #include "task.h" /* FreeRTOS task API */ #include "queue.h" /* FreeRTOS queue API */ #include "blinky_button.h" /* application shared interface */ #include "bsp.h" /* Board Support Package interface */ /*..........................................................................*/ int main() { BSP_init(); /* initialize the Board Support Package */ /* instantiate and start all FreeRTOS tasks and queues... */ TaskHandle_t th; /* Blinky1... */ static StaticQueue_t Blinky1_qcb; /* queue control block */ static Event *Blinky1_QSto[10]; /* queue storage */ QUEUE_Blinky1 = xQueueCreateStatic( ARRAY_NELEM(Blinky1_QSto), /* queue length */ sizeof(Event *), /* item size */ (uint8_t *)Blinky1_QSto, /* queue storage */ &Blinky1_qcb); /* queue control block */ configASSERT(QUEUE_Blinky1); static StaticTask_t Blinky1_tcb; /* task control block */ static StackType_t Blinky1_stack[configMINIMAL_STACK_SIZE]; th = xTaskCreateStatic( &Blinky1_task, /* task function */ "Blinky1", /* task priority */ ARRAY_NELEM(Blinky1_stack), /* stack length */ AO_Blinky1, /* task param */ 1U + tskIDLE_PRIORITY, /* task priority */ Blinky1_stack, /* task stack */ &Blinky1_tcb); /* task control block */ configASSERT(th); /* Button2a... */ static StaticQueue_t Button2a_qcb;/* queue control block */ static Event *Button2a_QSto[10]; /* queue storage */ QUEUE_Button2a = xQueueCreateStatic( ARRAY_NELEM(Button2a_QSto), /* queue length */ sizeof(Event *), /* item size */ (uint8_t *)Button2a_QSto, /* queue storage */ &Button2a_qcb); /* queue control block */ configASSERT(QUEUE_Button2a); static StaticTask_t Button2a_tcb; /* task control block */ static StackType_t Button2a_stack[configMINIMAL_STACK_SIZE]; th = xTaskCreateStatic( &Button2a_task, /* task function */ "Button2a", /* task priority */ ARRAY_NELEM(Button2a_stack), /* stack length */ AO_Button2a, /* task param */ 2U + tskIDLE_PRIORITY, /* task priority */ Button2a_stack, /* task stack */ &Button2a_tcb); /* task control block */ configASSERT(th); /* Button2b... */ static StaticQueue_t Button2b_qcb;/* queue control block */ static Event *Button2b_QSto[10]; /* queue storage */ QUEUE_Button2b = xQueueCreateStatic( ARRAY_NELEM(Button2b_QSto), /* queue length */ sizeof(Event *), /* item size */ (uint8_t *)Button2b_QSto, /* queue storage */ &Button2b_qcb); /* queue control block */ configASSERT(QUEUE_Button2b); static StaticTask_t Button2b_tcb; /* task control block */ static StackType_t Button2b_stack[configMINIMAL_STACK_SIZE]; th = xTaskCreateStatic( &Button2b_task, /* task function */ "Button2b", /* task priority */ ARRAY_NELEM(Button2b_stack), /* stack length */ AO_Button2b, /* task param */ 2U + tskIDLE_PRIORITY, /* task priority */ Button2b_stack, /* task stack */ &Button2b_tcb); /* task control block */ configASSERT(th); /* Blinky3... */ static StaticQueue_t Blinky3_qcb; /* queue control block */ static Event *Blinky3_QSto[10]; /* queue storage */ QUEUE_Blinky3 = xQueueCreateStatic( ARRAY_NELEM(Blinky3_QSto), /* queue length */ sizeof(Event *), /* item size */ (uint8_t *)Blinky3_QSto, /* queue storage */ &Blinky3_qcb); /* queue control block */ configASSERT(QUEUE_Blinky3); static StaticTask_t Blinky3_tcb; /* task control block */ static StackType_t Blinky3_stack[configMINIMAL_STACK_SIZE]; th = xTaskCreateStatic( &Blinky3_task, /* task function */ "Blinky3", /* task priority */ ARRAY_NELEM(Blinky3_stack), /* stack length */ AO_Blinky3, /* task param */ 3U + tskIDLE_PRIORITY, /* task priority */ Blinky3_stack, /* task stack */ &Blinky3_tcb); /* task control block */ configASSERT(th); vTaskStartScheduler(); /* start the FreeRTOS scheduler... */ return 0; /* NOTE: the scheduler does NOT return */ } ================================================ FILE: FreeRTOS-comparison/include/FreeRTOS.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef INC_FREERTOS_H #define INC_FREERTOS_H /* * Include the generic headers required for the FreeRTOS port being used. */ #include /* * If stdint.h cannot be located then: * + If using GCC ensure the -nostdint options is *not* being used. * + Ensure the project's include path includes the directory in which your * compiler stores stdint.h. * + Set any compiler options necessary for it to support C99, as technically * stdint.h is only mandatory with C99 (FreeRTOS does not require C99 in any * other way). * + The FreeRTOS download includes a simple stdint.h definition that can be * used in cases where none is provided by the compiler. The files only * contains the typedefs required to build FreeRTOS. Read the instructions * in FreeRTOS/source/stdint.readme for more information. */ #include /* READ COMMENT ABOVE. */ /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ /* Application specific configuration options. */ #include "FreeRTOSConfig.h" /* Basic FreeRTOS definitions. */ #include "projdefs.h" /* Definitions specific to the port being used. */ #include "portable.h" /* Must be defaulted before configUSE_NEWLIB_REENTRANT is used below. */ #ifndef configUSE_NEWLIB_REENTRANT #define configUSE_NEWLIB_REENTRANT 0 #endif /* Required if struct _reent is used. */ #if ( configUSE_NEWLIB_REENTRANT == 1 ) /* Note Newlib support has been included by popular demand, but is not * used by the FreeRTOS maintainers themselves. FreeRTOS is not * responsible for resulting newlib operation. User must be familiar with * newlib and must provide system-wide implementations of the necessary * stubs. Be warned that (at the time of writing) the current newlib design * implements a system-wide malloc() that must be provided with locks. * * See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html * for additional information. */ #include #define configUSE_C_RUNTIME_TLS_SUPPORT 1 #ifndef configTLS_BLOCK_TYPE #define configTLS_BLOCK_TYPE struct _reent #endif #ifndef configINIT_TLS_BLOCK #define configINIT_TLS_BLOCK( xTLSBlock ) _REENT_INIT_PTR( &( xTLSBlock ) ) #endif #ifndef configSET_TLS_BLOCK #define configSET_TLS_BLOCK( xTLSBlock ) _impure_ptr = &( xTLSBlock ) #endif #ifndef configDEINIT_TLS_BLOCK #define configDEINIT_TLS_BLOCK( xTLSBlock ) _reclaim_reent( &( xTLSBlock ) ) #endif #endif /* if ( configUSE_NEWLIB_REENTRANT == 1 ) */ #ifndef configUSE_C_RUNTIME_TLS_SUPPORT #define configUSE_C_RUNTIME_TLS_SUPPORT 0 #endif #if ( ( configUSE_NEWLIB_REENTRANT == 0 ) && ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) #ifndef configTLS_BLOCK_TYPE #error Missing definition: configTLS_BLOCK_TYPE must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1. #endif #ifndef configINIT_TLS_BLOCK #error Missing definition: configINIT_TLS_BLOCK must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1. #endif #ifndef configSET_TLS_BLOCK #error Missing definition: configSET_TLS_BLOCK must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1. #endif #ifndef configDEINIT_TLS_BLOCK #error Missing definition: configDEINIT_TLS_BLOCK must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1. #endif #endif /* if ( ( configUSE_NEWLIB_REENTRANT == 0 ) && ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) */ /* * Check all the required application specific macros have been defined. * These macros are application specific and (as downloaded) are defined * within FreeRTOSConfig.h. */ #ifndef configMINIMAL_STACK_SIZE #error Missing definition: configMINIMAL_STACK_SIZE must be defined in FreeRTOSConfig.h. configMINIMAL_STACK_SIZE defines the size (in words) of the stack allocated to the idle task. Refer to the demo project provided for your port for a suitable value. #endif #ifndef configMAX_PRIORITIES #error Missing definition: configMAX_PRIORITIES must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. #endif #if configMAX_PRIORITIES < 1 #error configMAX_PRIORITIES must be defined to be greater than or equal to 1. #endif #ifndef configUSE_PREEMPTION #error Missing definition: configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. #endif #ifndef configUSE_IDLE_HOOK #error Missing definition: configUSE_IDLE_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. #endif #ifndef configUSE_TICK_HOOK #error Missing definition: configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. #endif #ifndef configUSE_16_BIT_TICKS #error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. #endif #ifndef configUSE_CO_ROUTINES #define configUSE_CO_ROUTINES 0 #endif #ifndef INCLUDE_vTaskPrioritySet #define INCLUDE_vTaskPrioritySet 0 #endif #ifndef INCLUDE_uxTaskPriorityGet #define INCLUDE_uxTaskPriorityGet 0 #endif #ifndef INCLUDE_vTaskDelete #define INCLUDE_vTaskDelete 0 #endif #ifndef INCLUDE_vTaskSuspend #define INCLUDE_vTaskSuspend 0 #endif #ifdef INCLUDE_xTaskDelayUntil #ifdef INCLUDE_vTaskDelayUntil /* INCLUDE_vTaskDelayUntil was replaced by INCLUDE_xTaskDelayUntil. Backward * compatibility is maintained if only one or the other is defined, but * there is a conflict if both are defined. */ #error INCLUDE_vTaskDelayUntil and INCLUDE_xTaskDelayUntil are both defined. INCLUDE_vTaskDelayUntil is no longer required and should be removed #endif #endif #ifndef INCLUDE_xTaskDelayUntil #ifdef INCLUDE_vTaskDelayUntil /* If INCLUDE_vTaskDelayUntil is set but INCLUDE_xTaskDelayUntil is not then * the project's FreeRTOSConfig.h probably pre-dates the introduction of * xTaskDelayUntil and setting INCLUDE_xTaskDelayUntil to whatever * INCLUDE_vTaskDelayUntil is set to will ensure backward compatibility. */ #define INCLUDE_xTaskDelayUntil INCLUDE_vTaskDelayUntil #endif #endif #ifndef INCLUDE_xTaskDelayUntil #define INCLUDE_xTaskDelayUntil 0 #endif #ifndef INCLUDE_vTaskDelay #define INCLUDE_vTaskDelay 0 #endif #ifndef INCLUDE_xTaskGetIdleTaskHandle #define INCLUDE_xTaskGetIdleTaskHandle 0 #endif #ifndef INCLUDE_xTaskAbortDelay #define INCLUDE_xTaskAbortDelay 0 #endif #ifndef INCLUDE_xQueueGetMutexHolder #define INCLUDE_xQueueGetMutexHolder 0 #endif #ifndef INCLUDE_xSemaphoreGetMutexHolder #define INCLUDE_xSemaphoreGetMutexHolder INCLUDE_xQueueGetMutexHolder #endif #ifndef INCLUDE_xTaskGetHandle #define INCLUDE_xTaskGetHandle 0 #endif #ifndef INCLUDE_uxTaskGetStackHighWaterMark #define INCLUDE_uxTaskGetStackHighWaterMark 0 #endif #ifndef INCLUDE_uxTaskGetStackHighWaterMark2 #define INCLUDE_uxTaskGetStackHighWaterMark2 0 #endif #ifndef INCLUDE_eTaskGetState #define INCLUDE_eTaskGetState 0 #endif #ifndef INCLUDE_xTaskResumeFromISR #define INCLUDE_xTaskResumeFromISR 1 #endif #ifndef INCLUDE_xTimerPendFunctionCall #define INCLUDE_xTimerPendFunctionCall 0 #endif #ifndef INCLUDE_xTaskGetSchedulerState #define INCLUDE_xTaskGetSchedulerState 0 #endif #ifndef INCLUDE_xTaskGetCurrentTaskHandle #define INCLUDE_xTaskGetCurrentTaskHandle 1 #endif #if configUSE_CO_ROUTINES != 0 #ifndef configMAX_CO_ROUTINE_PRIORITIES #error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1. #endif #endif #ifndef configUSE_DAEMON_TASK_STARTUP_HOOK #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 #endif #ifndef configUSE_APPLICATION_TASK_TAG #define configUSE_APPLICATION_TASK_TAG 0 #endif #ifndef configNUM_THREAD_LOCAL_STORAGE_POINTERS #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0 #endif #ifndef configUSE_RECURSIVE_MUTEXES #define configUSE_RECURSIVE_MUTEXES 0 #endif #ifndef configUSE_MUTEXES #define configUSE_MUTEXES 0 #endif #ifndef configUSE_TIMERS #define configUSE_TIMERS 0 #endif #ifndef configUSE_COUNTING_SEMAPHORES #define configUSE_COUNTING_SEMAPHORES 0 #endif #ifndef configUSE_ALTERNATIVE_API #define configUSE_ALTERNATIVE_API 0 #endif #ifndef portCRITICAL_NESTING_IN_TCB #define portCRITICAL_NESTING_IN_TCB 0 #endif #ifndef configMAX_TASK_NAME_LEN #define configMAX_TASK_NAME_LEN 16 #endif #ifndef configIDLE_SHOULD_YIELD #define configIDLE_SHOULD_YIELD 1 #endif #if configMAX_TASK_NAME_LEN < 1 #error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h #endif #ifndef configASSERT #define configASSERT( x ) #define configASSERT_DEFINED 0 #else #define configASSERT_DEFINED 1 #endif /* configPRECONDITION should be defined as configASSERT. * The CBMC proofs need a way to track assumptions and assertions. * A configPRECONDITION statement should express an implicit invariant or * assumption made. A configASSERT statement should express an invariant that must * hold explicit before calling the code. */ #ifndef configPRECONDITION #define configPRECONDITION( X ) configASSERT( X ) #define configPRECONDITION_DEFINED 0 #else #define configPRECONDITION_DEFINED 1 #endif #ifndef portMEMORY_BARRIER #define portMEMORY_BARRIER() #endif #ifndef portSOFTWARE_BARRIER #define portSOFTWARE_BARRIER() #endif /* The timers module relies on xTaskGetSchedulerState(). */ #if configUSE_TIMERS == 1 #ifndef configTIMER_TASK_PRIORITY #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined. #endif /* configTIMER_TASK_PRIORITY */ #ifndef configTIMER_QUEUE_LENGTH #error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined. #endif /* configTIMER_QUEUE_LENGTH */ #ifndef configTIMER_TASK_STACK_DEPTH #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined. #endif /* configTIMER_TASK_STACK_DEPTH */ #endif /* configUSE_TIMERS */ #ifndef portSET_INTERRUPT_MASK_FROM_ISR #define portSET_INTERRUPT_MASK_FROM_ISR() 0 #endif #ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) ( uxSavedStatusValue ) #endif #ifndef portCLEAN_UP_TCB #define portCLEAN_UP_TCB( pxTCB ) ( void ) ( pxTCB ) #endif #ifndef portPRE_TASK_DELETE_HOOK #define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxYieldPending ) #endif #ifndef portSETUP_TCB #define portSETUP_TCB( pxTCB ) ( void ) ( pxTCB ) #endif #ifndef configQUEUE_REGISTRY_SIZE #define configQUEUE_REGISTRY_SIZE 0U #endif #if ( configQUEUE_REGISTRY_SIZE < 1 ) #define vQueueAddToRegistry( xQueue, pcName ) #define vQueueUnregisterQueue( xQueue ) #define pcQueueGetName( xQueue ) #endif #ifndef configUSE_MINI_LIST_ITEM #define configUSE_MINI_LIST_ITEM 1 #endif #ifndef portPOINTER_SIZE_TYPE #define portPOINTER_SIZE_TYPE uint32_t #endif /* Remove any unused trace macros. */ #ifndef traceSTART /* Used to perform any necessary initialisation - for example, open a file * into which trace is to be written. */ #define traceSTART() #endif #ifndef traceEND /* Use to close a trace, for example close a file into which trace has been * written. */ #define traceEND() #endif #ifndef traceTASK_SWITCHED_IN /* Called after a task has been selected to run. pxCurrentTCB holds a pointer * to the task control block of the selected task. */ #define traceTASK_SWITCHED_IN() #endif #ifndef traceINCREASE_TICK_COUNT /* Called before stepping the tick count after waking from tickless idle * sleep. */ #define traceINCREASE_TICK_COUNT( x ) #endif #ifndef traceLOW_POWER_IDLE_BEGIN /* Called immediately before entering tickless idle. */ #define traceLOW_POWER_IDLE_BEGIN() #endif #ifndef traceLOW_POWER_IDLE_END /* Called when returning to the Idle task after a tickless idle. */ #define traceLOW_POWER_IDLE_END() #endif #ifndef traceTASK_SWITCHED_OUT /* Called before a task has been selected to run. pxCurrentTCB holds a pointer * to the task control block of the task being switched out. */ #define traceTASK_SWITCHED_OUT() #endif #ifndef traceTASK_PRIORITY_INHERIT /* Called when a task attempts to take a mutex that is already held by a * lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task * that holds the mutex. uxInheritedPriority is the priority the mutex holder * will inherit (the priority of the task that is attempting to obtain the * muted. */ #define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority ) #endif #ifndef traceTASK_PRIORITY_DISINHERIT /* Called when a task releases a mutex, the holding of which had resulted in * the task inheriting the priority of a higher priority task. * pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the * mutex. uxOriginalPriority is the task's configured (base) priority. */ #define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority ) #endif #ifndef traceBLOCKING_ON_QUEUE_RECEIVE /* Task is about to block because it cannot read from a * queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore * upon which the read was attempted. pxCurrentTCB points to the TCB of the * task that attempted the read. */ #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) #endif #ifndef traceBLOCKING_ON_QUEUE_PEEK /* Task is about to block because it cannot read from a * queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore * upon which the read was attempted. pxCurrentTCB points to the TCB of the * task that attempted the read. */ #define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) #endif #ifndef traceBLOCKING_ON_QUEUE_SEND /* Task is about to block because it cannot write to a * queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore * upon which the write was attempted. pxCurrentTCB points to the TCB of the * task that attempted the write. */ #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) #endif #ifndef configCHECK_FOR_STACK_OVERFLOW #define configCHECK_FOR_STACK_OVERFLOW 0 #endif #ifndef configRECORD_STACK_HIGH_ADDRESS #define configRECORD_STACK_HIGH_ADDRESS 0 #endif #ifndef configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H #define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 0 #endif /* The following event macros are embedded in the kernel API calls. */ #ifndef traceMOVED_TASK_TO_READY_STATE #define traceMOVED_TASK_TO_READY_STATE( pxTCB ) #endif #ifndef tracePOST_MOVED_TASK_TO_READY_STATE #define tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB ) #endif #ifndef traceQUEUE_CREATE #define traceQUEUE_CREATE( pxNewQueue ) #endif #ifndef traceQUEUE_CREATE_FAILED #define traceQUEUE_CREATE_FAILED( ucQueueType ) #endif #ifndef traceCREATE_MUTEX #define traceCREATE_MUTEX( pxNewQueue ) #endif #ifndef traceCREATE_MUTEX_FAILED #define traceCREATE_MUTEX_FAILED() #endif #ifndef traceGIVE_MUTEX_RECURSIVE #define traceGIVE_MUTEX_RECURSIVE( pxMutex ) #endif #ifndef traceGIVE_MUTEX_RECURSIVE_FAILED #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) #endif #ifndef traceTAKE_MUTEX_RECURSIVE #define traceTAKE_MUTEX_RECURSIVE( pxMutex ) #endif #ifndef traceTAKE_MUTEX_RECURSIVE_FAILED #define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ) #endif #ifndef traceCREATE_COUNTING_SEMAPHORE #define traceCREATE_COUNTING_SEMAPHORE() #endif #ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED #define traceCREATE_COUNTING_SEMAPHORE_FAILED() #endif #ifndef traceQUEUE_SET_SEND #define traceQUEUE_SET_SEND traceQUEUE_SEND #endif #ifndef traceQUEUE_SEND #define traceQUEUE_SEND( pxQueue ) #endif #ifndef traceQUEUE_SEND_FAILED #define traceQUEUE_SEND_FAILED( pxQueue ) #endif #ifndef traceQUEUE_RECEIVE #define traceQUEUE_RECEIVE( pxQueue ) #endif #ifndef traceQUEUE_PEEK #define traceQUEUE_PEEK( pxQueue ) #endif #ifndef traceQUEUE_PEEK_FAILED #define traceQUEUE_PEEK_FAILED( pxQueue ) #endif #ifndef traceQUEUE_PEEK_FROM_ISR #define traceQUEUE_PEEK_FROM_ISR( pxQueue ) #endif #ifndef traceQUEUE_RECEIVE_FAILED #define traceQUEUE_RECEIVE_FAILED( pxQueue ) #endif #ifndef traceQUEUE_SEND_FROM_ISR #define traceQUEUE_SEND_FROM_ISR( pxQueue ) #endif #ifndef traceQUEUE_SEND_FROM_ISR_FAILED #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) #endif #ifndef traceQUEUE_RECEIVE_FROM_ISR #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) #endif #ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) #endif #ifndef traceQUEUE_PEEK_FROM_ISR_FAILED #define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ) #endif #ifndef traceQUEUE_DELETE #define traceQUEUE_DELETE( pxQueue ) #endif #ifndef traceTASK_CREATE #define traceTASK_CREATE( pxNewTCB ) #endif #ifndef traceTASK_CREATE_FAILED #define traceTASK_CREATE_FAILED() #endif #ifndef traceTASK_DELETE #define traceTASK_DELETE( pxTaskToDelete ) #endif #ifndef traceTASK_DELAY_UNTIL #define traceTASK_DELAY_UNTIL( x ) #endif #ifndef traceTASK_DELAY #define traceTASK_DELAY() #endif #ifndef traceTASK_PRIORITY_SET #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) #endif #ifndef traceTASK_SUSPEND #define traceTASK_SUSPEND( pxTaskToSuspend ) #endif #ifndef traceTASK_RESUME #define traceTASK_RESUME( pxTaskToResume ) #endif #ifndef traceTASK_RESUME_FROM_ISR #define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) #endif #ifndef traceTASK_INCREMENT_TICK #define traceTASK_INCREMENT_TICK( xTickCount ) #endif #ifndef traceTIMER_CREATE #define traceTIMER_CREATE( pxNewTimer ) #endif #ifndef traceTIMER_CREATE_FAILED #define traceTIMER_CREATE_FAILED() #endif #ifndef traceTIMER_COMMAND_SEND #define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn ) #endif #ifndef traceTIMER_EXPIRED #define traceTIMER_EXPIRED( pxTimer ) #endif #ifndef traceTIMER_COMMAND_RECEIVED #define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue ) #endif #ifndef traceMALLOC #define traceMALLOC( pvAddress, uiSize ) #endif #ifndef traceFREE #define traceFREE( pvAddress, uiSize ) #endif #ifndef traceEVENT_GROUP_CREATE #define traceEVENT_GROUP_CREATE( xEventGroup ) #endif #ifndef traceEVENT_GROUP_CREATE_FAILED #define traceEVENT_GROUP_CREATE_FAILED() #endif #ifndef traceEVENT_GROUP_SYNC_BLOCK #define traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ) #endif #ifndef traceEVENT_GROUP_SYNC_END #define traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) ( xTimeoutOccurred ) #endif #ifndef traceEVENT_GROUP_WAIT_BITS_BLOCK #define traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ) #endif #ifndef traceEVENT_GROUP_WAIT_BITS_END #define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) ( xTimeoutOccurred ) #endif #ifndef traceEVENT_GROUP_CLEAR_BITS #define traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ) #endif #ifndef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR #define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ) #endif #ifndef traceEVENT_GROUP_SET_BITS #define traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ) #endif #ifndef traceEVENT_GROUP_SET_BITS_FROM_ISR #define traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ) #endif #ifndef traceEVENT_GROUP_DELETE #define traceEVENT_GROUP_DELETE( xEventGroup ) #endif #ifndef tracePEND_FUNC_CALL #define tracePEND_FUNC_CALL( xFunctionToPend, pvParameter1, ulParameter2, ret ) #endif #ifndef tracePEND_FUNC_CALL_FROM_ISR #define tracePEND_FUNC_CALL_FROM_ISR( xFunctionToPend, pvParameter1, ulParameter2, ret ) #endif #ifndef traceQUEUE_REGISTRY_ADD #define traceQUEUE_REGISTRY_ADD( xQueue, pcQueueName ) #endif #ifndef traceTASK_NOTIFY_TAKE_BLOCK #define traceTASK_NOTIFY_TAKE_BLOCK( uxIndexToWait ) #endif #ifndef traceTASK_NOTIFY_TAKE #define traceTASK_NOTIFY_TAKE( uxIndexToWait ) #endif #ifndef traceTASK_NOTIFY_WAIT_BLOCK #define traceTASK_NOTIFY_WAIT_BLOCK( uxIndexToWait ) #endif #ifndef traceTASK_NOTIFY_WAIT #define traceTASK_NOTIFY_WAIT( uxIndexToWait ) #endif #ifndef traceTASK_NOTIFY #define traceTASK_NOTIFY( uxIndexToNotify ) #endif #ifndef traceTASK_NOTIFY_FROM_ISR #define traceTASK_NOTIFY_FROM_ISR( uxIndexToNotify ) #endif #ifndef traceTASK_NOTIFY_GIVE_FROM_ISR #define traceTASK_NOTIFY_GIVE_FROM_ISR( uxIndexToNotify ) #endif #ifndef traceSTREAM_BUFFER_CREATE_FAILED #define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) #endif #ifndef traceSTREAM_BUFFER_CREATE_STATIC_FAILED #define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) #endif #ifndef traceSTREAM_BUFFER_CREATE #define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) #endif #ifndef traceSTREAM_BUFFER_DELETE #define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) #endif #ifndef traceSTREAM_BUFFER_RESET #define traceSTREAM_BUFFER_RESET( xStreamBuffer ) #endif #ifndef traceBLOCKING_ON_STREAM_BUFFER_SEND #define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) #endif #ifndef traceSTREAM_BUFFER_SEND #define traceSTREAM_BUFFER_SEND( xStreamBuffer, xBytesSent ) #endif #ifndef traceSTREAM_BUFFER_SEND_FAILED #define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) #endif #ifndef traceSTREAM_BUFFER_SEND_FROM_ISR #define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xBytesSent ) #endif #ifndef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE #define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) #endif #ifndef traceSTREAM_BUFFER_RECEIVE #define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) #endif #ifndef traceSTREAM_BUFFER_RECEIVE_FAILED #define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) #endif #ifndef traceSTREAM_BUFFER_RECEIVE_FROM_ISR #define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) #endif #ifndef configGENERATE_RUN_TIME_STATS #define configGENERATE_RUN_TIME_STATS 0 #endif #if ( configGENERATE_RUN_TIME_STATS == 1 ) #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS #error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base. #endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */ #ifndef portGET_RUN_TIME_COUNTER_VALUE #ifndef portALT_GET_RUN_TIME_COUNTER_VALUE #error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information. #endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */ #endif /* portGET_RUN_TIME_COUNTER_VALUE */ #endif /* configGENERATE_RUN_TIME_STATS */ #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() #endif #ifndef configUSE_MALLOC_FAILED_HOOK #define configUSE_MALLOC_FAILED_HOOK 0 #endif #ifndef portPRIVILEGE_BIT #define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 ) #endif #ifndef portYIELD_WITHIN_API #define portYIELD_WITHIN_API portYIELD #endif #ifndef portSUPPRESS_TICKS_AND_SLEEP #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) #endif #ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 #endif #if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2 #error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2 #endif #ifndef configUSE_TICKLESS_IDLE #define configUSE_TICKLESS_IDLE 0 #endif #ifndef configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING #define configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( x ) #endif #ifndef configPRE_SLEEP_PROCESSING #define configPRE_SLEEP_PROCESSING( x ) #endif #ifndef configPOST_SLEEP_PROCESSING #define configPOST_SLEEP_PROCESSING( x ) #endif #ifndef configUSE_QUEUE_SETS #define configUSE_QUEUE_SETS 0 #endif #ifndef portTASK_USES_FLOATING_POINT #define portTASK_USES_FLOATING_POINT() #endif #ifndef portALLOCATE_SECURE_CONTEXT #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) #endif #ifndef portDONT_DISCARD #define portDONT_DISCARD #endif #ifndef configUSE_TIME_SLICING #define configUSE_TIME_SLICING 1 #endif #ifndef configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS #define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 #endif #ifndef configUSE_STATS_FORMATTING_FUNCTIONS #define configUSE_STATS_FORMATTING_FUNCTIONS 0 #endif #ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() #endif #ifndef configUSE_TRACE_FACILITY #define configUSE_TRACE_FACILITY 0 #endif #ifndef mtCOVERAGE_TEST_MARKER #define mtCOVERAGE_TEST_MARKER() #endif #ifndef mtCOVERAGE_TEST_DELAY #define mtCOVERAGE_TEST_DELAY() #endif #ifndef portASSERT_IF_IN_ISR #define portASSERT_IF_IN_ISR() #endif #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #endif #ifndef configAPPLICATION_ALLOCATED_HEAP #define configAPPLICATION_ALLOCATED_HEAP 0 #endif #ifndef configUSE_TASK_NOTIFICATIONS #define configUSE_TASK_NOTIFICATIONS 1 #endif #ifndef configTASK_NOTIFICATION_ARRAY_ENTRIES #define configTASK_NOTIFICATION_ARRAY_ENTRIES 1 #endif #if configTASK_NOTIFICATION_ARRAY_ENTRIES < 1 #error configTASK_NOTIFICATION_ARRAY_ENTRIES must be at least 1 #endif #ifndef configUSE_POSIX_ERRNO #define configUSE_POSIX_ERRNO 0 #endif #ifndef configUSE_SB_COMPLETED_CALLBACK /* By default per-instance callbacks are not enabled for stream buffer or message buffer. */ #define configUSE_SB_COMPLETED_CALLBACK 0 #endif #ifndef portTICK_TYPE_IS_ATOMIC #define portTICK_TYPE_IS_ATOMIC 0 #endif #ifndef configSUPPORT_STATIC_ALLOCATION /* Defaults to 0 for backward compatibility. */ #define configSUPPORT_STATIC_ALLOCATION 0 #endif #ifndef configSUPPORT_DYNAMIC_ALLOCATION /* Defaults to 1 for backward compatibility. */ #define configSUPPORT_DYNAMIC_ALLOCATION 1 #endif #if ( ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION != 1 ) ) #error configUSE_STATS_FORMATTING_FUNCTIONS cannot be used without dynamic allocation, but configSUPPORT_DYNAMIC_ALLOCATION is not set to 1. #endif #if ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) #if ( ( configUSE_TRACE_FACILITY != 1 ) && ( configGENERATE_RUN_TIME_STATS != 1 ) ) #error configUSE_STATS_FORMATTING_FUNCTIONS is 1 but the functions it enables are not used because neither configUSE_TRACE_FACILITY or configGENERATE_RUN_TIME_STATS are 1. Set configUSE_STATS_FORMATTING_FUNCTIONS to 0 in FreeRTOSConfig.h. #endif #endif #ifndef configSTACK_DEPTH_TYPE /* Defaults to uint16_t for backward compatibility, but can be overridden * in FreeRTOSConfig.h if uint16_t is too restrictive. */ #define configSTACK_DEPTH_TYPE uint16_t #endif #ifndef configRUN_TIME_COUNTER_TYPE /* Defaults to uint32_t for backward compatibility, but can be overridden in * FreeRTOSConfig.h if uint32_t is too restrictive. */ #define configRUN_TIME_COUNTER_TYPE uint32_t #endif #ifndef configMESSAGE_BUFFER_LENGTH_TYPE /* Defaults to size_t for backward compatibility, but can be overridden * in FreeRTOSConfig.h if lengths will always be less than the number of bytes * in a size_t. */ #define configMESSAGE_BUFFER_LENGTH_TYPE size_t #endif /* Sanity check the configuration. */ #if ( ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) ) #error configSUPPORT_STATIC_ALLOCATION and configSUPPORT_DYNAMIC_ALLOCATION cannot both be 0, but can both be 1. #endif #if ( ( configUSE_RECURSIVE_MUTEXES == 1 ) && ( configUSE_MUTEXES != 1 ) ) #error configUSE_MUTEXES must be set to 1 to use recursive mutexes #endif #ifndef configINITIAL_TICK_COUNT #define configINITIAL_TICK_COUNT 0 #endif #if ( portTICK_TYPE_IS_ATOMIC == 0 ) /* Either variables of tick type cannot be read atomically, or * portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when * the tick count is returned to the standard critical section macros. */ #define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL() #define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL() #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( ( x ) ) #else /* The tick type can be read atomically, so critical sections used when the * tick count is returned can be defined away. */ #define portTICK_TYPE_ENTER_CRITICAL() #define portTICK_TYPE_EXIT_CRITICAL() #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() 0 #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) ( void ) ( x ) #endif /* if ( portTICK_TYPE_IS_ATOMIC == 0 ) */ /* Definitions to allow backward compatibility with FreeRTOS versions prior to * V8 if desired. */ #ifndef configENABLE_BACKWARD_COMPATIBILITY #define configENABLE_BACKWARD_COMPATIBILITY 1 #endif #ifndef configPRINTF /* configPRINTF() was not defined, so define it away to nothing. To use * configPRINTF() then define it as follows (where MyPrintFunction() is * provided by the application writer): * * void MyPrintFunction(const char *pcFormat, ... ); #define configPRINTF( X ) MyPrintFunction X * * Then call like a standard printf() function, but placing brackets around * all parameters so they are passed as a single parameter. For example: * configPRINTF( ("Value = %d", MyVariable) ); */ #define configPRINTF( X ) #endif #ifndef configMAX /* The application writer has not provided their own MAX macro, so define * the following generic implementation. */ #define configMAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) #endif #ifndef configMIN /* The application writer has not provided their own MIN macro, so define * the following generic implementation. */ #define configMIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) #endif #if configENABLE_BACKWARD_COMPATIBILITY == 1 #define eTaskStateGet eTaskGetState #define portTickType TickType_t #define xTaskHandle TaskHandle_t #define xQueueHandle QueueHandle_t #define xSemaphoreHandle SemaphoreHandle_t #define xQueueSetHandle QueueSetHandle_t #define xQueueSetMemberHandle QueueSetMemberHandle_t #define xTimeOutType TimeOut_t #define xMemoryRegion MemoryRegion_t #define xTaskParameters TaskParameters_t #define xTaskStatusType TaskStatus_t #define xTimerHandle TimerHandle_t #define xCoRoutineHandle CoRoutineHandle_t #define pdTASK_HOOK_CODE TaskHookFunction_t #define portTICK_RATE_MS portTICK_PERIOD_MS #define pcTaskGetTaskName pcTaskGetName #define pcTimerGetTimerName pcTimerGetName #define pcQueueGetQueueName pcQueueGetName #define vTaskGetTaskInfo vTaskGetInfo #define xTaskGetIdleRunTimeCounter ulTaskGetIdleRunTimeCounter /* Backward compatibility within the scheduler code only - these definitions * are not really required but are included for completeness. */ #define tmrTIMER_CALLBACK TimerCallbackFunction_t #define pdTASK_CODE TaskFunction_t #define xListItem ListItem_t #define xList List_t /* For libraries that break the list data hiding, and access list structure * members directly (which is not supposed to be done). */ #define pxContainer pvContainer #endif /* configENABLE_BACKWARD_COMPATIBILITY */ #if ( configUSE_ALTERNATIVE_API != 0 ) #error The alternative API was deprecated some time ago, and was removed in FreeRTOS V9.0 0 #endif /* Set configUSE_TASK_FPU_SUPPORT to 0 to omit floating point support even * if floating point hardware is otherwise supported by the FreeRTOS port in use. * This constant is not supported by all FreeRTOS ports that include floating * point support. */ #ifndef configUSE_TASK_FPU_SUPPORT #define configUSE_TASK_FPU_SUPPORT 1 #endif /* Set configENABLE_MPU to 1 to enable MPU support and 0 to disable it. This is * currently used in ARMv8M ports. */ #ifndef configENABLE_MPU #define configENABLE_MPU 0 #endif /* Set configENABLE_FPU to 1 to enable FPU support and 0 to disable it. This is * currently used in ARMv8M ports. */ #ifndef configENABLE_FPU #define configENABLE_FPU 1 #endif /* Set configENABLE_MVE to 1 to enable MVE support and 0 to disable it. This is * currently used in ARMv8M ports. */ #ifndef configENABLE_MVE #define configENABLE_MVE 0 #endif /* Set configENABLE_TRUSTZONE to 1 enable TrustZone support and 0 to disable it. * This is currently used in ARMv8M ports. */ #ifndef configENABLE_TRUSTZONE #define configENABLE_TRUSTZONE 1 #endif /* Set configRUN_FREERTOS_SECURE_ONLY to 1 to run the FreeRTOS ARMv8M port on * the Secure Side only. */ #ifndef configRUN_FREERTOS_SECURE_ONLY #define configRUN_FREERTOS_SECURE_ONLY 0 #endif #ifndef configRUN_ADDITIONAL_TESTS #define configRUN_ADDITIONAL_TESTS 0 #endif /* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using * dynamically allocated RAM, in which case when any task is deleted it is known * that both the task's stack and TCB need to be freed. Sometimes the * FreeRTOSConfig.h settings only allow a task to be created using statically * allocated RAM, in which case when any task is deleted it is known that neither * the task's stack or TCB should be freed. Sometimes the FreeRTOSConfig.h * settings allow a task to be created using either statically or dynamically * allocated RAM, in which case a member of the TCB is used to record whether the * stack and/or TCB were allocated statically or dynamically, so when a task is * deleted the RAM that was allocated dynamically is freed again and no attempt is * made to free the RAM that was allocated statically. * tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is only true if it is possible for a * task to be created using either statically or dynamically allocated RAM. Note * that if portUSING_MPU_WRAPPERS is 1 then a protected task can be created with * a statically allocated stack and a dynamically allocated TCB. * * The following table lists various combinations of portUSING_MPU_WRAPPERS, * configSUPPORT_DYNAMIC_ALLOCATION and configSUPPORT_STATIC_ALLOCATION and * when it is possible to have both static and dynamic allocation: * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ * | MPU | Dynamic | Static | Available Functions | Possible Allocations | Both Dynamic and | Need Free | * | | | | | | Static Possible | | * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ * | 0 | 0 | 1 | xTaskCreateStatic | TCB - Static, Stack - Static | No | No | * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| * | 0 | 1 | 0 | xTaskCreate | TCB - Dynamic, Stack - Dynamic | No | Yes | * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| * | 0 | 1 | 1 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | * | | | | xTaskCreateStatic | 2. TCB - Static, Stack - Static | | | * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| * | 1 | 0 | 1 | xTaskCreateStatic, | TCB - Static, Stack - Static | No | No | * | | | | xTaskCreateRestrictedStatic | | | | * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| * | 1 | 1 | 0 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | * | | | | xTaskCreateRestricted | 2. TCB - Dynamic, Stack - Static | | | * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| * | 1 | 1 | 1 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | * | | | | xTaskCreateStatic, | 2. TCB - Dynamic, Stack - Static | | | * | | | | xTaskCreateRestricted, | 3. TCB - Static, Stack - Static | | | * | | | | xTaskCreateRestrictedStatic | | | | * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ */ #define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE \ ( ( ( portUSING_MPU_WRAPPERS == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) || \ ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) ) /* * In line with software engineering best practice, FreeRTOS implements a strict * data hiding policy, so the real structures used by FreeRTOS to maintain the * state of tasks, queues, semaphores, etc. are not accessible to the application * code. However, if the application writer wants to statically allocate such * an object then the size of the object needs to be known. Dummy structures * that are guaranteed to have the same size and alignment requirements of the * real objects are used for this purpose. The dummy list and list item * structures below are used for inclusion in such a dummy structure. */ struct xSTATIC_LIST_ITEM { #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) TickType_t xDummy1; #endif TickType_t xDummy2; void * pvDummy3[ 4 ]; #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) TickType_t xDummy4; #endif }; typedef struct xSTATIC_LIST_ITEM StaticListItem_t; #if ( configUSE_MINI_LIST_ITEM == 1 ) /* See the comments above the struct xSTATIC_LIST_ITEM definition. */ struct xSTATIC_MINI_LIST_ITEM { #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) TickType_t xDummy1; #endif TickType_t xDummy2; void * pvDummy3[ 2 ]; }; typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t; #else /* if ( configUSE_MINI_LIST_ITEM == 1 ) */ typedef struct xSTATIC_LIST_ITEM StaticMiniListItem_t; #endif /* if ( configUSE_MINI_LIST_ITEM == 1 ) */ /* See the comments above the struct xSTATIC_LIST_ITEM definition. */ typedef struct xSTATIC_LIST { #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) TickType_t xDummy1; #endif UBaseType_t uxDummy2; void * pvDummy3; StaticMiniListItem_t xDummy4; #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) TickType_t xDummy5; #endif } StaticList_t; /* * In line with software engineering best practice, especially when supplying a * library that is likely to change in future versions, FreeRTOS implements a * strict data hiding policy. This means the Task structure used internally by * FreeRTOS is not accessible to application code. However, if the application * writer wants to statically allocate the memory required to create a task then * the size of the task object needs to be known. The StaticTask_t structure * below is provided for this purpose. Its sizes and alignment requirements are * guaranteed to match those of the genuine structure, no matter which * architecture is being used, and no matter how the values in FreeRTOSConfig.h * are set. Its contents are somewhat obfuscated in the hope users will * recognise that it would be unwise to make direct use of the structure members. */ typedef struct xSTATIC_TCB { void * pxDummy1; #if ( portUSING_MPU_WRAPPERS == 1 ) xMPU_SETTINGS xDummy2; #endif StaticListItem_t xDummy3[ 2 ]; UBaseType_t uxDummy5; void * pxDummy6; uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ]; #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) void * pxDummy8; #endif #if ( portCRITICAL_NESTING_IN_TCB == 1 ) UBaseType_t uxDummy9; #endif #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxDummy10[ 2 ]; #endif #if ( configUSE_MUTEXES == 1 ) UBaseType_t uxDummy12[ 2 ]; #endif #if ( configUSE_APPLICATION_TASK_TAG == 1 ) void * pxDummy14; #endif #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) void * pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; #endif #if ( configGENERATE_RUN_TIME_STATS == 1 ) configRUN_TIME_COUNTER_TYPE ulDummy16; #endif #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) configTLS_BLOCK_TYPE xDummy17; #endif #if ( configUSE_TASK_NOTIFICATIONS == 1 ) uint32_t ulDummy18[ configTASK_NOTIFICATION_ARRAY_ENTRIES ]; uint8_t ucDummy19[ configTASK_NOTIFICATION_ARRAY_ENTRIES ]; #endif #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) uint8_t uxDummy20; #endif #if ( INCLUDE_xTaskAbortDelay == 1 ) uint8_t ucDummy21; #endif #if ( configUSE_POSIX_ERRNO == 1 ) int iDummy22; #endif } StaticTask_t; /* * In line with software engineering best practice, especially when supplying a * library that is likely to change in future versions, FreeRTOS implements a * strict data hiding policy. This means the Queue structure used internally by * FreeRTOS is not accessible to application code. However, if the application * writer wants to statically allocate the memory required to create a queue * then the size of the queue object needs to be known. The StaticQueue_t * structure below is provided for this purpose. Its sizes and alignment * requirements are guaranteed to match those of the genuine structure, no * matter which architecture is being used, and no matter how the values in * FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in the hope * users will recognise that it would be unwise to make direct use of the * structure members. */ typedef struct xSTATIC_QUEUE { void * pvDummy1[ 3 ]; union { void * pvDummy2; UBaseType_t uxDummy2; } u; StaticList_t xDummy3[ 2 ]; UBaseType_t uxDummy4[ 3 ]; uint8_t ucDummy5[ 2 ]; #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) uint8_t ucDummy6; #endif #if ( configUSE_QUEUE_SETS == 1 ) void * pvDummy7; #endif #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxDummy8; uint8_t ucDummy9; #endif } StaticQueue_t; typedef StaticQueue_t StaticSemaphore_t; /* * In line with software engineering best practice, especially when supplying a * library that is likely to change in future versions, FreeRTOS implements a * strict data hiding policy. This means the event group structure used * internally by FreeRTOS is not accessible to application code. However, if * the application writer wants to statically allocate the memory required to * create an event group then the size of the event group object needs to be * know. The StaticEventGroup_t structure below is provided for this purpose. * Its sizes and alignment requirements are guaranteed to match those of the * genuine structure, no matter which architecture is being used, and no matter * how the values in FreeRTOSConfig.h are set. Its contents are somewhat * obfuscated in the hope users will recognise that it would be unwise to make * direct use of the structure members. */ typedef struct xSTATIC_EVENT_GROUP { TickType_t xDummy1; StaticList_t xDummy2; #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxDummy3; #endif #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) uint8_t ucDummy4; #endif } StaticEventGroup_t; /* * In line with software engineering best practice, especially when supplying a * library that is likely to change in future versions, FreeRTOS implements a * strict data hiding policy. This means the software timer structure used * internally by FreeRTOS is not accessible to application code. However, if * the application writer wants to statically allocate the memory required to * create a software timer then the size of the queue object needs to be known. * The StaticTimer_t structure below is provided for this purpose. Its sizes * and alignment requirements are guaranteed to match those of the genuine * structure, no matter which architecture is being used, and no matter how the * values in FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in * the hope users will recognise that it would be unwise to make direct use of * the structure members. */ typedef struct xSTATIC_TIMER { void * pvDummy1; StaticListItem_t xDummy2; TickType_t xDummy3; void * pvDummy5; TaskFunction_t pvDummy6; #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxDummy7; #endif uint8_t ucDummy8; } StaticTimer_t; /* * In line with software engineering best practice, especially when supplying a * library that is likely to change in future versions, FreeRTOS implements a * strict data hiding policy. This means the stream buffer structure used * internally by FreeRTOS is not accessible to application code. However, if * the application writer wants to statically allocate the memory required to * create a stream buffer then the size of the stream buffer object needs to be * known. The StaticStreamBuffer_t structure below is provided for this * purpose. Its size and alignment requirements are guaranteed to match those * of the genuine structure, no matter which architecture is being used, and * no matter how the values in FreeRTOSConfig.h are set. Its contents are * somewhat obfuscated in the hope users will recognise that it would be unwise * to make direct use of the structure members. */ typedef struct xSTATIC_STREAM_BUFFER { size_t uxDummy1[ 4 ]; void * pvDummy2[ 3 ]; uint8_t ucDummy3; #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxDummy4; #endif #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) void * pvDummy5[ 2 ]; #endif } StaticStreamBuffer_t; /* Message buffers are built on stream buffers. */ typedef StaticStreamBuffer_t StaticMessageBuffer_t; /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* INC_FREERTOS_H */ ================================================ FILE: FreeRTOS-comparison/include/StackMacros.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef _MSC_VER /* Visual Studio doesn't support #warning. */ #warning The name of this file has changed to stack_macros.h. Please update your code accordingly. This source file (which has the original name) will be removed in a future release. #endif #include "stack_macros.h" ================================================ FILE: FreeRTOS-comparison/include/atomic.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /** * @file atomic.h * @brief FreeRTOS atomic operation support. * * This file implements atomic functions by disabling interrupts globally. * Implementations with architecture specific atomic instructions can be * provided under each compiler directory. */ #ifndef ATOMIC_H #define ATOMIC_H #ifndef INC_FREERTOS_H #error "include FreeRTOS.h must appear in source files before include atomic.h" #endif /* Standard includes. */ #include /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ /* * Port specific definitions -- entering/exiting critical section. * Refer template -- ./lib/FreeRTOS/portable/Compiler/Arch/portmacro.h * * Every call to ATOMIC_EXIT_CRITICAL() must be closely paired with * ATOMIC_ENTER_CRITICAL(). * */ #if defined( portSET_INTERRUPT_MASK_FROM_ISR ) /* Nested interrupt scheme is supported in this port. */ #define ATOMIC_ENTER_CRITICAL() \ UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR() #define ATOMIC_EXIT_CRITICAL() \ portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType ) #else /* Nested interrupt scheme is NOT supported in this port. */ #define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL() #define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL() #endif /* portSET_INTERRUPT_MASK_FROM_ISR() */ /* * Port specific definition -- "always inline". * Inline is compiler specific, and may not always get inlined depending on your * optimization level. Also, inline is considered as performance optimization * for atomic. Thus, if portFORCE_INLINE is not provided by portmacro.h, * instead of resulting error, simply define it away. */ #ifndef portFORCE_INLINE #define portFORCE_INLINE #endif #define ATOMIC_COMPARE_AND_SWAP_SUCCESS 0x1U /**< Compare and swap succeeded, swapped. */ #define ATOMIC_COMPARE_AND_SWAP_FAILURE 0x0U /**< Compare and swap failed, did not swap. */ /*----------------------------- Swap && CAS ------------------------------*/ /** * Atomic compare-and-swap * * @brief Performs an atomic compare-and-swap operation on the specified values. * * @param[in, out] pulDestination Pointer to memory location from where value is * to be loaded and checked. * @param[in] ulExchange If condition meets, write this value to memory. * @param[in] ulComparand Swap condition. * * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped. * * @note This function only swaps *pulDestination with ulExchange, if previous * *pulDestination value equals ulComparand. */ static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32( uint32_t volatile * pulDestination, uint32_t ulExchange, uint32_t ulComparand ) { uint32_t ulReturnValue; ATOMIC_ENTER_CRITICAL(); { if( *pulDestination == ulComparand ) { *pulDestination = ulExchange; ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS; } else { ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE; } } ATOMIC_EXIT_CRITICAL(); return ulReturnValue; } /*-----------------------------------------------------------*/ /** * Atomic swap (pointers) * * @brief Atomically sets the address pointed to by *ppvDestination to the value * of *pvExchange. * * @param[in, out] ppvDestination Pointer to memory location from where a pointer * value is to be loaded and written back to. * @param[in] pvExchange Pointer value to be written to *ppvDestination. * * @return The initial value of *ppvDestination. */ static portFORCE_INLINE void * Atomic_SwapPointers_p32( void * volatile * ppvDestination, void * pvExchange ) { void * pReturnValue; ATOMIC_ENTER_CRITICAL(); { pReturnValue = *ppvDestination; *ppvDestination = pvExchange; } ATOMIC_EXIT_CRITICAL(); return pReturnValue; } /*-----------------------------------------------------------*/ /** * Atomic compare-and-swap (pointers) * * @brief Performs an atomic compare-and-swap operation on the specified pointer * values. * * @param[in, out] ppvDestination Pointer to memory location from where a pointer * value is to be loaded and checked. * @param[in] pvExchange If condition meets, write this value to memory. * @param[in] pvComparand Swap condition. * * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped. * * @note This function only swaps *ppvDestination with pvExchange, if previous * *ppvDestination value equals pvComparand. */ static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32( void * volatile * ppvDestination, void * pvExchange, void * pvComparand ) { uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE; ATOMIC_ENTER_CRITICAL(); { if( *ppvDestination == pvComparand ) { *ppvDestination = pvExchange; ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS; } } ATOMIC_EXIT_CRITICAL(); return ulReturnValue; } /*----------------------------- Arithmetic ------------------------------*/ /** * Atomic add * * @brief Atomically adds count to the value of the specified pointer points to. * * @param[in,out] pulAddend Pointer to memory location from where value is to be * loaded and written back to. * @param[in] ulCount Value to be added to *pulAddend. * * @return previous *pulAddend value. */ static portFORCE_INLINE uint32_t Atomic_Add_u32( uint32_t volatile * pulAddend, uint32_t ulCount ) { uint32_t ulCurrent; ATOMIC_ENTER_CRITICAL(); { ulCurrent = *pulAddend; *pulAddend += ulCount; } ATOMIC_EXIT_CRITICAL(); return ulCurrent; } /*-----------------------------------------------------------*/ /** * Atomic subtract * * @brief Atomically subtracts count from the value of the specified pointer * pointers to. * * @param[in,out] pulAddend Pointer to memory location from where value is to be * loaded and written back to. * @param[in] ulCount Value to be subtract from *pulAddend. * * @return previous *pulAddend value. */ static portFORCE_INLINE uint32_t Atomic_Subtract_u32( uint32_t volatile * pulAddend, uint32_t ulCount ) { uint32_t ulCurrent; ATOMIC_ENTER_CRITICAL(); { ulCurrent = *pulAddend; *pulAddend -= ulCount; } ATOMIC_EXIT_CRITICAL(); return ulCurrent; } /*-----------------------------------------------------------*/ /** * Atomic increment * * @brief Atomically increments the value of the specified pointer points to. * * @param[in,out] pulAddend Pointer to memory location from where value is to be * loaded and written back to. * * @return *pulAddend value before increment. */ static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pulAddend ) { uint32_t ulCurrent; ATOMIC_ENTER_CRITICAL(); { ulCurrent = *pulAddend; *pulAddend += 1; } ATOMIC_EXIT_CRITICAL(); return ulCurrent; } /*-----------------------------------------------------------*/ /** * Atomic decrement * * @brief Atomically decrements the value of the specified pointer points to * * @param[in,out] pulAddend Pointer to memory location from where value is to be * loaded and written back to. * * @return *pulAddend value before decrement. */ static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pulAddend ) { uint32_t ulCurrent; ATOMIC_ENTER_CRITICAL(); { ulCurrent = *pulAddend; *pulAddend -= 1; } ATOMIC_EXIT_CRITICAL(); return ulCurrent; } /*----------------------------- Bitwise Logical ------------------------------*/ /** * Atomic OR * * @brief Performs an atomic OR operation on the specified values. * * @param [in, out] pulDestination Pointer to memory location from where value is * to be loaded and written back to. * @param [in] ulValue Value to be ORed with *pulDestination. * * @return The original value of *pulDestination. */ static portFORCE_INLINE uint32_t Atomic_OR_u32( uint32_t volatile * pulDestination, uint32_t ulValue ) { uint32_t ulCurrent; ATOMIC_ENTER_CRITICAL(); { ulCurrent = *pulDestination; *pulDestination |= ulValue; } ATOMIC_EXIT_CRITICAL(); return ulCurrent; } /*-----------------------------------------------------------*/ /** * Atomic AND * * @brief Performs an atomic AND operation on the specified values. * * @param [in, out] pulDestination Pointer to memory location from where value is * to be loaded and written back to. * @param [in] ulValue Value to be ANDed with *pulDestination. * * @return The original value of *pulDestination. */ static portFORCE_INLINE uint32_t Atomic_AND_u32( uint32_t volatile * pulDestination, uint32_t ulValue ) { uint32_t ulCurrent; ATOMIC_ENTER_CRITICAL(); { ulCurrent = *pulDestination; *pulDestination &= ulValue; } ATOMIC_EXIT_CRITICAL(); return ulCurrent; } /*-----------------------------------------------------------*/ /** * Atomic NAND * * @brief Performs an atomic NAND operation on the specified values. * * @param [in, out] pulDestination Pointer to memory location from where value is * to be loaded and written back to. * @param [in] ulValue Value to be NANDed with *pulDestination. * * @return The original value of *pulDestination. */ static portFORCE_INLINE uint32_t Atomic_NAND_u32( uint32_t volatile * pulDestination, uint32_t ulValue ) { uint32_t ulCurrent; ATOMIC_ENTER_CRITICAL(); { ulCurrent = *pulDestination; *pulDestination = ~( ulCurrent & ulValue ); } ATOMIC_EXIT_CRITICAL(); return ulCurrent; } /*-----------------------------------------------------------*/ /** * Atomic XOR * * @brief Performs an atomic XOR operation on the specified values. * * @param [in, out] pulDestination Pointer to memory location from where value is * to be loaded and written back to. * @param [in] ulValue Value to be XORed with *pulDestination. * * @return The original value of *pulDestination. */ static portFORCE_INLINE uint32_t Atomic_XOR_u32( uint32_t volatile * pulDestination, uint32_t ulValue ) { uint32_t ulCurrent; ATOMIC_ENTER_CRITICAL(); { ulCurrent = *pulDestination; *pulDestination ^= ulValue; } ATOMIC_EXIT_CRITICAL(); return ulCurrent; } /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* ATOMIC_H */ ================================================ FILE: FreeRTOS-comparison/include/croutine.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef CO_ROUTINE_H #define CO_ROUTINE_H #ifndef INC_FREERTOS_H #error "include FreeRTOS.h must appear in source files before include croutine.h" #endif #include "list.h" /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ /* Used to hide the implementation of the co-routine control block. The * control block structure however has to be included in the header due to * the macro implementation of the co-routine functionality. */ typedef void * CoRoutineHandle_t; /* Defines the prototype to which co-routine functions must conform. */ typedef void (* crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t ); typedef struct corCoRoutineControlBlock { crCOROUTINE_CODE pxCoRoutineFunction; ListItem_t xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */ ListItem_t xEventListItem; /*< List item used to place the CRCB in event lists. */ UBaseType_t uxPriority; /*< The priority of the co-routine in relation to other co-routines. */ UBaseType_t uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */ uint16_t uxState; /*< Used internally by the co-routine implementation. */ } CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */ /** * croutine. h * @code{c} * BaseType_t xCoRoutineCreate( * crCOROUTINE_CODE pxCoRoutineCode, * UBaseType_t uxPriority, * UBaseType_t uxIndex * ); * @endcode * * Create a new co-routine and add it to the list of co-routines that are * ready to run. * * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine * functions require special syntax - see the co-routine section of the WEB * documentation for more information. * * @param uxPriority The priority with respect to other co-routines at which * the co-routine will run. * * @param uxIndex Used to distinguish between different co-routines that * execute the same function. See the example below and the co-routine section * of the WEB documentation for further information. * * @return pdPASS if the co-routine was successfully created and added to a ready * list, otherwise an error code defined with ProjDefs.h. * * Example usage: * @code{c} * // Co-routine to be created. * void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * { * // Variables in co-routines must be declared static if they must maintain value across a blocking call. * // This may not be necessary for const variables. * static const char cLedToFlash[ 2 ] = { 5, 6 }; * static const TickType_t uxFlashRates[ 2 ] = { 200, 400 }; * * // Must start every co-routine with a call to crSTART(); * crSTART( xHandle ); * * for( ;; ) * { * // This co-routine just delays for a fixed period, then toggles * // an LED. Two co-routines are created using this function, so * // the uxIndex parameter is used to tell the co-routine which * // LED to flash and how int32_t to delay. This assumes xQueue has * // already been created. * vParTestToggleLED( cLedToFlash[ uxIndex ] ); * crDELAY( xHandle, uxFlashRates[ uxIndex ] ); * } * * // Must end every co-routine with a call to crEND(); * crEND(); * } * * // Function that creates two co-routines. * void vOtherFunction( void ) * { * uint8_t ucParameterToPass; * TaskHandle_t xHandle; * * // Create two co-routines at priority 0. The first is given index 0 * // so (from the code above) toggles LED 5 every 200 ticks. The second * // is given index 1 so toggles LED 6 every 400 ticks. * for( uxIndex = 0; uxIndex < 2; uxIndex++ ) * { * xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex ); * } * } * @endcode * \defgroup xCoRoutineCreate xCoRoutineCreate * \ingroup Tasks */ BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ); /** * croutine. h * @code{c} * void vCoRoutineSchedule( void ); * @endcode * * Run a co-routine. * * vCoRoutineSchedule() executes the highest priority co-routine that is able * to run. The co-routine will execute until it either blocks, yields or is * preempted by a task. Co-routines execute cooperatively so one * co-routine cannot be preempted by another, but can be preempted by a task. * * If an application comprises of both tasks and co-routines then * vCoRoutineSchedule should be called from the idle task (in an idle task * hook). * * Example usage: * @code{c} * // This idle task hook will schedule a co-routine each time it is called. * // The rest of the idle task will execute between co-routine calls. * void vApplicationIdleHook( void ) * { * vCoRoutineSchedule(); * } * * // Alternatively, if you do not require any other part of the idle task to * // execute, the idle task hook can call vCoRoutineSchedule() within an * // infinite loop. * void vApplicationIdleHook( void ) * { * for( ;; ) * { * vCoRoutineSchedule(); * } * } * @endcode * \defgroup vCoRoutineSchedule vCoRoutineSchedule * \ingroup Tasks */ void vCoRoutineSchedule( void ); /** * croutine. h * @code{c} * crSTART( CoRoutineHandle_t xHandle ); * @endcode * * This macro MUST always be called at the start of a co-routine function. * * Example usage: * @code{c} * // Co-routine to be created. * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * { * // Variables in co-routines must be declared static if they must maintain value across a blocking call. * static int32_t ulAVariable; * * // Must start every co-routine with a call to crSTART(); * crSTART( xHandle ); * * for( ;; ) * { * // Co-routine functionality goes here. * } * * // Must end every co-routine with a call to crEND(); * crEND(); * } * @endcode * \defgroup crSTART crSTART * \ingroup Tasks */ #define crSTART( pxCRCB ) \ switch( ( ( CRCB_t * ) ( pxCRCB ) )->uxState ) { \ case 0: /** * croutine. h * @code{c} * crEND(); * @endcode * * This macro MUST always be called at the end of a co-routine function. * * Example usage: * @code{c} * // Co-routine to be created. * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * { * // Variables in co-routines must be declared static if they must maintain value across a blocking call. * static int32_t ulAVariable; * * // Must start every co-routine with a call to crSTART(); * crSTART( xHandle ); * * for( ;; ) * { * // Co-routine functionality goes here. * } * * // Must end every co-routine with a call to crEND(); * crEND(); * } * @endcode * \defgroup crSTART crSTART * \ingroup Tasks */ #define crEND() } /* * These macros are intended for internal use by the co-routine implementation * only. The macros should not be used directly by application writers. */ #define crSET_STATE0( xHandle ) \ ( ( CRCB_t * ) ( xHandle ) )->uxState = ( __LINE__ * 2 ); return; \ case ( __LINE__ * 2 ): #define crSET_STATE1( xHandle ) \ ( ( CRCB_t * ) ( xHandle ) )->uxState = ( ( __LINE__ * 2 ) + 1 ); return; \ case ( ( __LINE__ * 2 ) + 1 ): /** * croutine. h * @code{c} * crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay ); * @endcode * * Delay a co-routine for a fixed period of time. * * crDELAY can only be called from the co-routine function itself - not * from within a function called by the co-routine function. This is because * co-routines do not maintain their own stack. * * @param xHandle The handle of the co-routine to delay. This is the xHandle * parameter of the co-routine function. * * @param xTickToDelay The number of ticks that the co-routine should delay * for. The actual amount of time this equates to is defined by * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_PERIOD_MS * can be used to convert ticks to milliseconds. * * Example usage: * @code{c} * // Co-routine to be created. * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * { * // Variables in co-routines must be declared static if they must maintain value across a blocking call. * // This may not be necessary for const variables. * // We are to delay for 200ms. * static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS; * * // Must start every co-routine with a call to crSTART(); * crSTART( xHandle ); * * for( ;; ) * { * // Delay for 200ms. * crDELAY( xHandle, xDelayTime ); * * // Do something here. * } * * // Must end every co-routine with a call to crEND(); * crEND(); * } * @endcode * \defgroup crDELAY crDELAY * \ingroup Tasks */ #define crDELAY( xHandle, xTicksToDelay ) \ if( ( xTicksToDelay ) > 0 ) \ { \ vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \ } \ crSET_STATE0( ( xHandle ) ); /** * @code{c} * crQUEUE_SEND( * CoRoutineHandle_t xHandle, * QueueHandle_t pxQueue, * void *pvItemToQueue, * TickType_t xTicksToWait, * BaseType_t *pxResult * ) * @endcode * * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. * * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas * xQueueSend() and xQueueReceive() can only be used from tasks. * * crQUEUE_SEND can only be called from the co-routine function itself - not * from within a function called by the co-routine function. This is because * co-routines do not maintain their own stack. * * See the co-routine section of the WEB documentation for information on * passing data between tasks and co-routines and between ISR's and * co-routines. * * @param xHandle The handle of the calling co-routine. This is the xHandle * parameter of the co-routine function. * * @param pxQueue The handle of the queue on which the data will be posted. * The handle is obtained as the return value when the queue is created using * the xQueueCreate() API function. * * @param pvItemToQueue A pointer to the data being posted onto the queue. * The number of bytes of each queued item is specified when the queue is * created. This number of bytes is copied from pvItemToQueue into the queue * itself. * * @param xTickToDelay The number of ticks that the co-routine should block * to wait for space to become available on the queue, should space not be * available immediately. The actual amount of time this equates to is defined * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example * below). * * @param pxResult The variable pointed to by pxResult will be set to pdPASS if * data was successfully posted onto the queue, otherwise it will be set to an * error defined within ProjDefs.h. * * Example usage: * @code{c} * // Co-routine function that blocks for a fixed period then posts a number onto * // a queue. * static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * { * // Variables in co-routines must be declared static if they must maintain value across a blocking call. * static BaseType_t xNumberToPost = 0; * static BaseType_t xResult; * * // Co-routines must begin with a call to crSTART(). * crSTART( xHandle ); * * for( ;; ) * { * // This assumes the queue has already been created. * crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult ); * * if( xResult != pdPASS ) * { * // The message was not posted! * } * * // Increment the number to be posted onto the queue. * xNumberToPost++; * * // Delay for 100 ticks. * crDELAY( xHandle, 100 ); * } * * // Co-routines must end with a call to crEND(). * crEND(); * } * @endcode * \defgroup crQUEUE_SEND crQUEUE_SEND * \ingroup Tasks */ #define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \ { \ *( pxResult ) = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), ( xTicksToWait ) ); \ if( *( pxResult ) == errQUEUE_BLOCKED ) \ { \ crSET_STATE0( ( xHandle ) ); \ *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \ } \ if( *pxResult == errQUEUE_YIELD ) \ { \ crSET_STATE1( ( xHandle ) ); \ *pxResult = pdPASS; \ } \ } /** * croutine. h * @code{c} * crQUEUE_RECEIVE( * CoRoutineHandle_t xHandle, * QueueHandle_t pxQueue, * void *pvBuffer, * TickType_t xTicksToWait, * BaseType_t *pxResult * ) * @endcode * * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. * * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas * xQueueSend() and xQueueReceive() can only be used from tasks. * * crQUEUE_RECEIVE can only be called from the co-routine function itself - not * from within a function called by the co-routine function. This is because * co-routines do not maintain their own stack. * * See the co-routine section of the WEB documentation for information on * passing data between tasks and co-routines and between ISR's and * co-routines. * * @param xHandle The handle of the calling co-routine. This is the xHandle * parameter of the co-routine function. * * @param pxQueue The handle of the queue from which the data will be received. * The handle is obtained as the return value when the queue is created using * the xQueueCreate() API function. * * @param pvBuffer The buffer into which the received item is to be copied. * The number of bytes of each queued item is specified when the queue is * created. This number of bytes is copied into pvBuffer. * * @param xTickToDelay The number of ticks that the co-routine should block * to wait for data to become available from the queue, should data not be * available immediately. The actual amount of time this equates to is defined * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the * crQUEUE_SEND example). * * @param pxResult The variable pointed to by pxResult will be set to pdPASS if * data was successfully retrieved from the queue, otherwise it will be set to * an error code as defined within ProjDefs.h. * * Example usage: * @code{c} * // A co-routine receives the number of an LED to flash from a queue. It * // blocks on the queue until the number is received. * static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * { * // Variables in co-routines must be declared static if they must maintain value across a blocking call. * static BaseType_t xResult; * static UBaseType_t uxLEDToFlash; * * // All co-routines must start with a call to crSTART(). * crSTART( xHandle ); * * for( ;; ) * { * // Wait for data to become available on the queue. * crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult ); * * if( xResult == pdPASS ) * { * // We received the LED to flash - flash it! * vParTestToggleLED( uxLEDToFlash ); * } * } * * crEND(); * } * @endcode * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE * \ingroup Tasks */ #define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \ { \ *( pxResult ) = xQueueCRReceive( ( pxQueue ), ( pvBuffer ), ( xTicksToWait ) ); \ if( *( pxResult ) == errQUEUE_BLOCKED ) \ { \ crSET_STATE0( ( xHandle ) ); \ *( pxResult ) = xQueueCRReceive( ( pxQueue ), ( pvBuffer ), 0 ); \ } \ if( *( pxResult ) == errQUEUE_YIELD ) \ { \ crSET_STATE1( ( xHandle ) ); \ *( pxResult ) = pdPASS; \ } \ } /** * croutine. h * @code{c} * crQUEUE_SEND_FROM_ISR( * QueueHandle_t pxQueue, * void *pvItemToQueue, * BaseType_t xCoRoutinePreviouslyWoken * ) * @endcode * * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() * functions used by tasks. * * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and * xQueueReceiveFromISR() can only be used to pass data between a task and and * ISR. * * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue * that is being used from within a co-routine. * * See the co-routine section of the WEB documentation for information on * passing data between tasks and co-routines and between ISR's and * co-routines. * * @param xQueue The handle to the queue on which the item is to be posted. * * @param pvItemToQueue A pointer to the item that is to be placed on the * queue. The size of the items the queue will hold was defined when the * queue was created, so this many bytes will be copied from pvItemToQueue * into the queue storage area. * * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto * the same queue multiple times from a single interrupt. The first call * should always pass in pdFALSE. Subsequent calls should pass in * the value returned from the previous call. * * @return pdTRUE if a co-routine was woken by posting onto the queue. This is * used by the ISR to determine if a context switch may be required following * the ISR. * * Example usage: * @code{c} * // A co-routine that blocks on a queue waiting for characters to be received. * static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * { * char cRxedChar; * BaseType_t xResult; * * // All co-routines must start with a call to crSTART(). * crSTART( xHandle ); * * for( ;; ) * { * // Wait for data to become available on the queue. This assumes the * // queue xCommsRxQueue has already been created! * crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult ); * * // Was a character received? * if( xResult == pdPASS ) * { * // Process the character here. * } * } * * // All co-routines must end with a call to crEND(). * crEND(); * } * * // An ISR that uses a queue to send characters received on a serial port to * // a co-routine. * void vUART_ISR( void ) * { * char cRxedChar; * BaseType_t xCRWokenByPost = pdFALSE; * * // We loop around reading characters until there are none left in the UART. * while( UART_RX_REG_NOT_EMPTY() ) * { * // Obtain the character from the UART. * cRxedChar = UART_RX_REG; * * // Post the character onto a queue. xCRWokenByPost will be pdFALSE * // the first time around the loop. If the post causes a co-routine * // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE. * // In this manner we can ensure that if more than one co-routine is * // blocked on the queue only one is woken by this ISR no matter how * // many characters are posted to the queue. * xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost ); * } * } * @endcode * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR * \ingroup Tasks */ #define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) \ xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) ) /** * croutine. h * @code{c} * crQUEUE_SEND_FROM_ISR( * QueueHandle_t pxQueue, * void *pvBuffer, * BaseType_t * pxCoRoutineWoken * ) * @endcode * * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() * functions used by tasks. * * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and * xQueueReceiveFromISR() can only be used to pass data between a task and and * ISR. * * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data * from a queue that is being used from within a co-routine (a co-routine * posted to the queue). * * See the co-routine section of the WEB documentation for information on * passing data between tasks and co-routines and between ISR's and * co-routines. * * @param xQueue The handle to the queue on which the item is to be posted. * * @param pvBuffer A pointer to a buffer into which the received item will be * placed. The size of the items the queue will hold was defined when the * queue was created, so this many bytes will be copied from the queue into * pvBuffer. * * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise * *pxCoRoutineWoken will remain unchanged. * * @return pdTRUE an item was successfully received from the queue, otherwise * pdFALSE. * * Example usage: * @code{c} * // A co-routine that posts a character to a queue then blocks for a fixed * // period. The character is incremented each time. * static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * { * // cChar holds its value while this co-routine is blocked and must therefore * // be declared static. * static char cCharToTx = 'a'; * BaseType_t xResult; * * // All co-routines must start with a call to crSTART(). * crSTART( xHandle ); * * for( ;; ) * { * // Send the next character to the queue. * crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult ); * * if( xResult == pdPASS ) * { * // The character was successfully posted to the queue. * } * else * { * // Could not post the character to the queue. * } * * // Enable the UART Tx interrupt to cause an interrupt in this * // hypothetical UART. The interrupt will obtain the character * // from the queue and send it. * ENABLE_RX_INTERRUPT(); * * // Increment to the next character then block for a fixed period. * // cCharToTx will maintain its value across the delay as it is * // declared static. * cCharToTx++; * if( cCharToTx > 'x' ) * { * cCharToTx = 'a'; * } * crDELAY( 100 ); * } * * // All co-routines must end with a call to crEND(). * crEND(); * } * * // An ISR that uses a queue to receive characters to send on a UART. * void vUART_ISR( void ) * { * char cCharToTx; * BaseType_t xCRWokenByPost = pdFALSE; * * while( UART_TX_REG_EMPTY() ) * { * // Are there any characters in the queue waiting to be sent? * // xCRWokenByPost will automatically be set to pdTRUE if a co-routine * // is woken by the post - ensuring that only a single co-routine is * // woken no matter how many times we go around this loop. * if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) ) * { * SEND_CHARACTER( cCharToTx ); * } * } * } * @endcode * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR * \ingroup Tasks */ #define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) \ xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) ) /* * This function is intended for internal use by the co-routine macros only. * The macro nature of the co-routine implementation requires that the * prototype appears here. The function should not be used by application * writers. * * Removes the current co-routine from its ready list and places it in the * appropriate delayed list. */ void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t * pxEventList ); /* * This function is intended for internal use by the queue implementation only. * The function should not be used by application writers. * * Removes the highest priority co-routine from the event list and places it in * the pending ready list. */ BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList ); /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* CO_ROUTINE_H */ ================================================ FILE: FreeRTOS-comparison/include/deprecated_definitions.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef DEPRECATED_DEFINITIONS_H #define DEPRECATED_DEFINITIONS_H /* Each FreeRTOS port has a unique portmacro.h header file. Originally a * pre-processor definition was used to ensure the pre-processor found the correct * portmacro.h file for the port being used. That scheme was deprecated in favour * of setting the compiler's include path such that it found the correct * portmacro.h file - removing the need for the constant and allowing the * portmacro.h file to be located anywhere in relation to the port being used. The * definitions below remain in the code for backward compatibility only. New * projects should not use them. */ #ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" typedef void ( __interrupt __far * pxISR )(); #endif #ifdef OPEN_WATCOM_FLASH_LITE_186_PORT #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" typedef void ( __interrupt __far * pxISR )(); #endif #ifdef GCC_MEGA_AVR #include "../portable/GCC/ATMega323/portmacro.h" #endif #ifdef IAR_MEGA_AVR #include "../portable/IAR/ATMega323/portmacro.h" #endif #ifdef MPLAB_PIC24_PORT #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" #endif #ifdef MPLAB_DSPIC_PORT #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" #endif #ifdef MPLAB_PIC18F_PORT #include "../../Source/portable/MPLAB/PIC18F/portmacro.h" #endif #ifdef MPLAB_PIC32MX_PORT #include "../../Source/portable/MPLAB/PIC32MX/portmacro.h" #endif #ifdef _FEDPICC #include "libFreeRTOS/Include/portmacro.h" #endif #ifdef SDCC_CYGNAL #include "../../Source/portable/SDCC/Cygnal/portmacro.h" #endif #ifdef GCC_ARM7 #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" #endif #ifdef GCC_ARM7_ECLIPSE #include "portmacro.h" #endif #ifdef ROWLEY_LPC23xx #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" #endif #ifdef IAR_MSP430 #include "..\..\Source\portable\IAR\MSP430\portmacro.h" #endif #ifdef GCC_MSP430 #include "../../Source/portable/GCC/MSP430F449/portmacro.h" #endif #ifdef ROWLEY_MSP430 #include "../../Source/portable/Rowley/MSP430F449/portmacro.h" #endif #ifdef ARM7_LPC21xx_KEIL_RVDS #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" #endif #ifdef SAM7_GCC #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" #endif #ifdef SAM7_IAR #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" #endif #ifdef SAM9XE_IAR #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" #endif #ifdef LPC2000_IAR #include "..\..\Source\portable\IAR\LPC2000\portmacro.h" #endif #ifdef STR71X_IAR #include "..\..\Source\portable\IAR\STR71x\portmacro.h" #endif #ifdef STR75X_IAR #include "..\..\Source\portable\IAR\STR75x\portmacro.h" #endif #ifdef STR75X_GCC #include "..\..\Source\portable\GCC\STR75x\portmacro.h" #endif #ifdef STR91X_IAR #include "..\..\Source\portable\IAR\STR91x\portmacro.h" #endif #ifdef GCC_H8S #include "../../Source/portable/GCC/H8S2329/portmacro.h" #endif #ifdef GCC_AT91FR40008 #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" #endif #ifdef RVDS_ARMCM3_LM3S102 #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" #endif #ifdef GCC_ARMCM3_LM3S102 #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" #endif #ifdef GCC_ARMCM3 #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" #endif #ifdef IAR_ARM_CM3 #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" #endif #ifdef IAR_ARMCM3_LM #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" #endif #ifdef HCS12_CODE_WARRIOR #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" #endif #ifdef MICROBLAZE_GCC #include "../../Source/portable/GCC/MicroBlaze/portmacro.h" #endif #ifdef TERN_EE #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" #endif #ifdef GCC_HCS12 #include "../../Source/portable/GCC/HCS12/portmacro.h" #endif #ifdef GCC_MCF5235 #include "../../Source/portable/GCC/MCF5235/portmacro.h" #endif #ifdef COLDFIRE_V2_GCC #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" #endif #ifdef COLDFIRE_V2_CODEWARRIOR #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" #endif #ifdef GCC_PPC405 #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" #endif #ifdef GCC_PPC440 #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" #endif #ifdef _16FX_SOFTUNE #include "..\..\Source\portable\Softune\MB96340\portmacro.h" #endif #ifdef BCC_INDUSTRIAL_PC_PORT /* A short file name has to be used in place of the normal * FreeRTOSConfig.h when using the Borland compiler. */ #include "frconfig.h" #include "..\portable\BCC\16BitDOS\PC\prtmacro.h" typedef void ( __interrupt __far * pxISR )(); #endif #ifdef BCC_FLASH_LITE_186_PORT /* A short file name has to be used in place of the normal * FreeRTOSConfig.h when using the Borland compiler. */ #include "frconfig.h" #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" typedef void ( __interrupt __far * pxISR )(); #endif #ifdef __GNUC__ #ifdef __AVR32_AVR32A__ #include "portmacro.h" #endif #endif #ifdef __ICCAVR32__ #ifdef __CORE__ #if __CORE__ == __AVR32A__ #include "portmacro.h" #endif #endif #endif #ifdef __91467D #include "portmacro.h" #endif #ifdef __96340 #include "portmacro.h" #endif #ifdef __IAR_V850ES_Fx3__ #include "../../Source/portable/IAR/V850ES/portmacro.h" #endif #ifdef __IAR_V850ES_Jx3__ #include "../../Source/portable/IAR/V850ES/portmacro.h" #endif #ifdef __IAR_V850ES_Jx3_L__ #include "../../Source/portable/IAR/V850ES/portmacro.h" #endif #ifdef __IAR_V850ES_Jx2__ #include "../../Source/portable/IAR/V850ES/portmacro.h" #endif #ifdef __IAR_V850ES_Hx2__ #include "../../Source/portable/IAR/V850ES/portmacro.h" #endif #ifdef __IAR_78K0R_Kx3__ #include "../../Source/portable/IAR/78K0R/portmacro.h" #endif #ifdef __IAR_78K0R_Kx3L__ #include "../../Source/portable/IAR/78K0R/portmacro.h" #endif #endif /* DEPRECATED_DEFINITIONS_H */ ================================================ FILE: FreeRTOS-comparison/include/event_groups.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef EVENT_GROUPS_H #define EVENT_GROUPS_H #ifndef INC_FREERTOS_H #error "include FreeRTOS.h" must appear in source files before "include event_groups.h" #endif /* FreeRTOS includes. */ #include "timers.h" /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ /** * An event group is a collection of bits to which an application can assign a * meaning. For example, an application may create an event group to convey * the status of various CAN bus related events in which bit 0 might mean "A CAN * message has been received and is ready for processing", bit 1 might mean "The * application has queued a message that is ready for sending onto the CAN * network", and bit 2 might mean "It is time to send a SYNC message onto the * CAN network" etc. A task can then test the bit values to see which events * are active, and optionally enter the Blocked state to wait for a specified * bit or a group of specified bits to be active. To continue the CAN bus * example, a CAN controlling task can enter the Blocked state (and therefore * not consume any processing time) until either bit 0, bit 1 or bit 2 are * active, at which time the bit that was actually active would inform the task * which action it had to take (process a received message, send a message, or * send a SYNC). * * The event groups implementation contains intelligence to avoid race * conditions that would otherwise occur were an application to use a simple * variable for the same purpose. This is particularly important with respect * to when a bit within an event group is to be cleared, and when bits have to * be set and then tested atomically - as is the case where event groups are * used to create a synchronisation point between multiple tasks (a * 'rendezvous'). */ /** * event_groups.h * * Type by which event groups are referenced. For example, a call to * xEventGroupCreate() returns an EventGroupHandle_t variable that can then * be used as a parameter to other event group functions. * * \defgroup EventGroupHandle_t EventGroupHandle_t * \ingroup EventGroup */ struct EventGroupDef_t; typedef struct EventGroupDef_t * EventGroupHandle_t; /* * The type that holds event bits always matches TickType_t - therefore the * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1, * 32 bits if set to 0. * * \defgroup EventBits_t EventBits_t * \ingroup EventGroup */ typedef TickType_t EventBits_t; /** * event_groups.h * @code{c} * EventGroupHandle_t xEventGroupCreate( void ); * @endcode * * Create a new event group. * * Internally, within the FreeRTOS implementation, event groups use a [small] * block of memory, in which the event group's structure is stored. If an event * groups is created using xEventGroupCreate() then the required memory is * automatically dynamically allocated inside the xEventGroupCreate() function. * (see https://www.FreeRTOS.org/a00111.html). If an event group is created * using xEventGroupCreateStatic() then the application writer must instead * provide the memory that will get used by the event group. * xEventGroupCreateStatic() therefore allows an event group to be created * without using any dynamic memory allocation. * * Although event groups are not related to ticks, for internal implementation * reasons the number of bits available for use in an event group is dependent * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store * event bits within an event group. * * @return If the event group was created then a handle to the event group is * returned. If there was insufficient FreeRTOS heap available to create the * event group then NULL is returned. See https://www.FreeRTOS.org/a00111.html * * Example usage: * @code{c} * // Declare a variable to hold the created event group. * EventGroupHandle_t xCreatedEventGroup; * * // Attempt to create the event group. * xCreatedEventGroup = xEventGroupCreate(); * * // Was the event group created successfully? * if( xCreatedEventGroup == NULL ) * { * // The event group was not created because there was insufficient * // FreeRTOS heap available. * } * else * { * // The event group was created. * } * @endcode * \defgroup xEventGroupCreate xEventGroupCreate * \ingroup EventGroup */ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION; #endif /** * event_groups.h * @code{c} * EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer ); * @endcode * * Create a new event group. * * Internally, within the FreeRTOS implementation, event groups use a [small] * block of memory, in which the event group's structure is stored. If an event * groups is created using xEventGroupCreate() then the required memory is * automatically dynamically allocated inside the xEventGroupCreate() function. * (see https://www.FreeRTOS.org/a00111.html). If an event group is created * using xEventGroupCreateStatic() then the application writer must instead * provide the memory that will get used by the event group. * xEventGroupCreateStatic() therefore allows an event group to be created * without using any dynamic memory allocation. * * Although event groups are not related to ticks, for internal implementation * reasons the number of bits available for use in an event group is dependent * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store * event bits within an event group. * * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type * StaticEventGroup_t, which will be then be used to hold the event group's data * structures, removing the need for the memory to be allocated dynamically. * * @return If the event group was created then a handle to the event group is * returned. If pxEventGroupBuffer was NULL then NULL is returned. * * Example usage: * @code{c} * // StaticEventGroup_t is a publicly accessible structure that has the same * // size and alignment requirements as the real event group structure. It is * // provided as a mechanism for applications to know the size of the event * // group (which is dependent on the architecture and configuration file * // settings) without breaking the strict data hiding policy by exposing the * // real event group internals. This StaticEventGroup_t variable is passed * // into the xSemaphoreCreateEventGroupStatic() function and is used to store * // the event group's data structures * StaticEventGroup_t xEventGroupBuffer; * * // Create the event group without dynamically allocating any memory. * xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer ); * @endcode */ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) PRIVILEGED_FUNCTION; #endif /** * event_groups.h * @code{c} * EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, * const EventBits_t uxBitsToWaitFor, * const BaseType_t xClearOnExit, * const BaseType_t xWaitForAllBits, * const TickType_t xTicksToWait ); * @endcode * * [Potentially] block to wait for one or more bits to be set within a * previously created event group. * * This function cannot be called from an interrupt. * * @param xEventGroup The event group in which the bits are being tested. The * event group must have previously been created using a call to * xEventGroupCreate(). * * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test * inside the event group. For example, to wait for bit 0 and/or bit 2 set * uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set * uxBitsToWaitFor to 0x07. Etc. * * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within * uxBitsToWaitFor that are set within the event group will be cleared before * xEventGroupWaitBits() returns if the wait condition was met (if the function * returns for a reason other than a timeout). If xClearOnExit is set to * pdFALSE then the bits set in the event group are not altered when the call to * xEventGroupWaitBits() returns. * * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor * are set or the specified block time expires. If xWaitForAllBits is set to * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set * in uxBitsToWaitFor is set or the specified block time expires. The block * time is specified by the xTicksToWait parameter. * * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait * for one/all (depending on the xWaitForAllBits value) of the bits specified by * uxBitsToWaitFor to become set. A value of portMAX_DELAY can be used to block * indefinitely (provided INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). * * @return The value of the event group at the time either the bits being waited * for became set, or the block time expired. Test the return value to know * which bits were set. If xEventGroupWaitBits() returned because its timeout * expired then not all the bits being waited for will be set. If * xEventGroupWaitBits() returned because the bits it was waiting for were set * then the returned value is the event group value before any bits were * automatically cleared in the case that xClearOnExit parameter was set to * pdTRUE. * * Example usage: * @code{c} * #define BIT_0 ( 1 << 0 ) * #define BIT_4 ( 1 << 4 ) * * void aFunction( EventGroupHandle_t xEventGroup ) * { * EventBits_t uxBits; * const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS; * * // Wait a maximum of 100ms for either bit 0 or bit 4 to be set within * // the event group. Clear the bits before exiting. * uxBits = xEventGroupWaitBits( * xEventGroup, // The event group being tested. * BIT_0 | BIT_4, // The bits within the event group to wait for. * pdTRUE, // BIT_0 and BIT_4 should be cleared before returning. * pdFALSE, // Don't wait for both bits, either bit will do. * xTicksToWait ); // Wait a maximum of 100ms for either bit to be set. * * if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) * { * // xEventGroupWaitBits() returned because both bits were set. * } * else if( ( uxBits & BIT_0 ) != 0 ) * { * // xEventGroupWaitBits() returned because just BIT_0 was set. * } * else if( ( uxBits & BIT_4 ) != 0 ) * { * // xEventGroupWaitBits() returned because just BIT_4 was set. * } * else * { * // xEventGroupWaitBits() returned because xTicksToWait ticks passed * // without either BIT_0 or BIT_4 becoming set. * } * } * @endcode * \defgroup xEventGroupWaitBits xEventGroupWaitBits * \ingroup EventGroup */ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** * event_groups.h * @code{c} * EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ); * @endcode * * Clear bits within an event group. This function cannot be called from an * interrupt. * * @param xEventGroup The event group in which the bits are to be cleared. * * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear * in the event group. For example, to clear bit 3 only, set uxBitsToClear to * 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09. * * @return The value of the event group before the specified bits were cleared. * * Example usage: * @code{c} * #define BIT_0 ( 1 << 0 ) * #define BIT_4 ( 1 << 4 ) * * void aFunction( EventGroupHandle_t xEventGroup ) * { * EventBits_t uxBits; * * // Clear bit 0 and bit 4 in xEventGroup. * uxBits = xEventGroupClearBits( * xEventGroup, // The event group being updated. * BIT_0 | BIT_4 );// The bits being cleared. * * if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) * { * // Both bit 0 and bit 4 were set before xEventGroupClearBits() was * // called. Both will now be clear (not set). * } * else if( ( uxBits & BIT_0 ) != 0 ) * { * // Bit 0 was set before xEventGroupClearBits() was called. It will * // now be clear. * } * else if( ( uxBits & BIT_4 ) != 0 ) * { * // Bit 4 was set before xEventGroupClearBits() was called. It will * // now be clear. * } * else * { * // Neither bit 0 nor bit 4 were set in the first place. * } * } * @endcode * \defgroup xEventGroupClearBits xEventGroupClearBits * \ingroup EventGroup */ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; /** * event_groups.h * @code{c} * BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); * @endcode * * A version of xEventGroupClearBits() that can be called from an interrupt. * * Setting bits in an event group is not a deterministic operation because there * are an unknown number of tasks that may be waiting for the bit or bits being * set. FreeRTOS does not allow nondeterministic operations to be performed * while interrupts are disabled, so protects event groups that are accessed * from tasks by suspending the scheduler rather than disabling interrupts. As * a result event groups cannot be accessed directly from an interrupt service * routine. Therefore xEventGroupClearBitsFromISR() sends a message to the * timer task to have the clear operation performed in the context of the timer * task. * * @note If this function returns pdPASS then the timer task is ready to run * and a portYIELD_FROM_ISR(pdTRUE) should be executed to perform the needed * clear on the event group. This behavior is different from * xEventGroupSetBitsFromISR because the parameter xHigherPriorityTaskWoken is * not present. * * @param xEventGroup The event group in which the bits are to be cleared. * * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear. * For example, to clear bit 3 only, set uxBitsToClear to 0x08. To clear bit 3 * and bit 0 set uxBitsToClear to 0x09. * * @return If the request to execute the function was posted successfully then * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned * if the timer service queue was full. * * Example usage: * @code{c} * #define BIT_0 ( 1 << 0 ) * #define BIT_4 ( 1 << 4 ) * * // An event group which it is assumed has already been created by a call to * // xEventGroupCreate(). * EventGroupHandle_t xEventGroup; * * void anInterruptHandler( void ) * { * // Clear bit 0 and bit 4 in xEventGroup. * xResult = xEventGroupClearBitsFromISR( * xEventGroup, // The event group being updated. * BIT_0 | BIT_4 ); // The bits being set. * * if( xResult == pdPASS ) * { * // The message was posted successfully. * portYIELD_FROM_ISR(pdTRUE); * } * } * @endcode * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR * \ingroup EventGroup */ #if ( configUSE_TRACE_FACILITY == 1 ) BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; #else #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) \ xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) ( xEventGroup ), ( uint32_t ) ( uxBitsToClear ), NULL ) #endif /** * event_groups.h * @code{c} * EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); * @endcode * * Set bits within an event group. * This function cannot be called from an interrupt. xEventGroupSetBitsFromISR() * is a version that can be called from an interrupt. * * Setting bits in an event group will automatically unblock tasks that are * blocked waiting for the bits. * * @param xEventGroup The event group in which the bits are to be set. * * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 * and bit 0 set uxBitsToSet to 0x09. * * @return The value of the event group at the time the call to * xEventGroupSetBits() returns. There are two reasons why the returned value * might have the bits specified by the uxBitsToSet parameter cleared. First, * if setting a bit results in a task that was waiting for the bit leaving the * blocked state then it is possible the bit will be cleared automatically * (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any * unblocked (or otherwise Ready state) task that has a priority above that of * the task that called xEventGroupSetBits() will execute and may change the * event group value before the call to xEventGroupSetBits() returns. * * Example usage: * @code{c} * #define BIT_0 ( 1 << 0 ) * #define BIT_4 ( 1 << 4 ) * * void aFunction( EventGroupHandle_t xEventGroup ) * { * EventBits_t uxBits; * * // Set bit 0 and bit 4 in xEventGroup. * uxBits = xEventGroupSetBits( * xEventGroup, // The event group being updated. * BIT_0 | BIT_4 );// The bits being set. * * if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) * { * // Both bit 0 and bit 4 remained set when the function returned. * } * else if( ( uxBits & BIT_0 ) != 0 ) * { * // Bit 0 remained set when the function returned, but bit 4 was * // cleared. It might be that bit 4 was cleared automatically as a * // task that was waiting for bit 4 was removed from the Blocked * // state. * } * else if( ( uxBits & BIT_4 ) != 0 ) * { * // Bit 4 remained set when the function returned, but bit 0 was * // cleared. It might be that bit 0 was cleared automatically as a * // task that was waiting for bit 0 was removed from the Blocked * // state. * } * else * { * // Neither bit 0 nor bit 4 remained set. It might be that a task * // was waiting for both of the bits to be set, and the bits were * // cleared as the task left the Blocked state. * } * } * @endcode * \defgroup xEventGroupSetBits xEventGroupSetBits * \ingroup EventGroup */ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; /** * event_groups.h * @code{c} * BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ); * @endcode * * A version of xEventGroupSetBits() that can be called from an interrupt. * * Setting bits in an event group is not a deterministic operation because there * are an unknown number of tasks that may be waiting for the bit or bits being * set. FreeRTOS does not allow nondeterministic operations to be performed in * interrupts or from critical sections. Therefore xEventGroupSetBitsFromISR() * sends a message to the timer task to have the set operation performed in the * context of the timer task - where a scheduler lock is used in place of a * critical section. * * @param xEventGroup The event group in which the bits are to be set. * * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 * and bit 0 set uxBitsToSet to 0x09. * * @param pxHigherPriorityTaskWoken As mentioned above, calling this function * will result in a message being sent to the timer daemon task. If the * priority of the timer daemon task is higher than the priority of the * currently running task (the task the interrupt interrupted) then * *pxHigherPriorityTaskWoken will be set to pdTRUE by * xEventGroupSetBitsFromISR(), indicating that a context switch should be * requested before the interrupt exits. For that reason * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the * example code below. * * @return If the request to execute the function was posted successfully then * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned * if the timer service queue was full. * * Example usage: * @code{c} * #define BIT_0 ( 1 << 0 ) * #define BIT_4 ( 1 << 4 ) * * // An event group which it is assumed has already been created by a call to * // xEventGroupCreate(). * EventGroupHandle_t xEventGroup; * * void anInterruptHandler( void ) * { * BaseType_t xHigherPriorityTaskWoken, xResult; * * // xHigherPriorityTaskWoken must be initialised to pdFALSE. * xHigherPriorityTaskWoken = pdFALSE; * * // Set bit 0 and bit 4 in xEventGroup. * xResult = xEventGroupSetBitsFromISR( * xEventGroup, // The event group being updated. * BIT_0 | BIT_4 // The bits being set. * &xHigherPriorityTaskWoken ); * * // Was the message posted successfully? * if( xResult == pdPASS ) * { * // If xHigherPriorityTaskWoken is now set to pdTRUE then a context * // switch should be requested. The macro used is port specific and * // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - * // refer to the documentation page for the port being used. * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * } * } * @endcode * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR * \ingroup EventGroup */ #if ( configUSE_TRACE_FACILITY == 1 ) BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; #else #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) \ xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) ( xEventGroup ), ( uint32_t ) ( uxBitsToSet ), ( pxHigherPriorityTaskWoken ) ) #endif /** * event_groups.h * @code{c} * EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, * const EventBits_t uxBitsToSet, * const EventBits_t uxBitsToWaitFor, * TickType_t xTicksToWait ); * @endcode * * Atomically set bits within an event group, then wait for a combination of * bits to be set within the same event group. This functionality is typically * used to synchronise multiple tasks, where each task has to wait for the other * tasks to reach a synchronisation point before proceeding. * * This function cannot be used from an interrupt. * * The function will return before its block time expires if the bits specified * by the uxBitsToWait parameter are set, or become set within that time. In * this case all the bits specified by uxBitsToWait will be automatically * cleared before the function returns. * * @param xEventGroup The event group in which the bits are being tested. The * event group must have previously been created using a call to * xEventGroupCreate(). * * @param uxBitsToSet The bits to set in the event group before determining * if, and possibly waiting for, all the bits specified by the uxBitsToWait * parameter are set. * * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test * inside the event group. For example, to wait for bit 0 and bit 2 set * uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set * uxBitsToWaitFor to 0x07. Etc. * * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait * for all of the bits specified by uxBitsToWaitFor to become set. * * @return The value of the event group at the time either the bits being waited * for became set, or the block time expired. Test the return value to know * which bits were set. If xEventGroupSync() returned because its timeout * expired then not all the bits being waited for will be set. If * xEventGroupSync() returned because all the bits it was waiting for were * set then the returned value is the event group value before any bits were * automatically cleared. * * Example usage: * @code{c} * // Bits used by the three tasks. * #define TASK_0_BIT ( 1 << 0 ) * #define TASK_1_BIT ( 1 << 1 ) * #define TASK_2_BIT ( 1 << 2 ) * * #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT ) * * // Use an event group to synchronise three tasks. It is assumed this event * // group has already been created elsewhere. * EventGroupHandle_t xEventBits; * * void vTask0( void *pvParameters ) * { * EventBits_t uxReturn; * TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS; * * for( ;; ) * { * // Perform task functionality here. * * // Set bit 0 in the event flag to note this task has reached the * // sync point. The other two tasks will set the other two bits defined * // by ALL_SYNC_BITS. All three tasks have reached the synchronisation * // point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms * // for this to happen. * uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait ); * * if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS ) * { * // All three tasks reached the synchronisation point before the call * // to xEventGroupSync() timed out. * } * } * } * * void vTask1( void *pvParameters ) * { * for( ;; ) * { * // Perform task functionality here. * * // Set bit 1 in the event flag to note this task has reached the * // synchronisation point. The other two tasks will set the other two * // bits defined by ALL_SYNC_BITS. All three tasks have reached the * // synchronisation point when all the ALL_SYNC_BITS are set. Wait * // indefinitely for this to happen. * xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY ); * * // xEventGroupSync() was called with an indefinite block time, so * // this task will only reach here if the synchronisation was made by all * // three tasks, so there is no need to test the return value. * } * } * * void vTask2( void *pvParameters ) * { * for( ;; ) * { * // Perform task functionality here. * * // Set bit 2 in the event flag to note this task has reached the * // synchronisation point. The other two tasks will set the other two * // bits defined by ALL_SYNC_BITS. All three tasks have reached the * // synchronisation point when all the ALL_SYNC_BITS are set. Wait * // indefinitely for this to happen. * xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY ); * * // xEventGroupSync() was called with an indefinite block time, so * // this task will only reach here if the synchronisation was made by all * // three tasks, so there is no need to test the return value. * } * } * * @endcode * \defgroup xEventGroupSync xEventGroupSync * \ingroup EventGroup */ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** * event_groups.h * @code{c} * EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup ); * @endcode * * Returns the current value of the bits in an event group. This function * cannot be used from an interrupt. * * @param xEventGroup The event group being queried. * * @return The event group bits at the time xEventGroupGetBits() was called. * * \defgroup xEventGroupGetBits xEventGroupGetBits * \ingroup EventGroup */ #define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( ( xEventGroup ), 0 ) /** * event_groups.h * @code{c} * EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ); * @endcode * * A version of xEventGroupGetBits() that can be called from an ISR. * * @param xEventGroup The event group being queried. * * @return The event group bits at the time xEventGroupGetBitsFromISR() was called. * * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR * \ingroup EventGroup */ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; /** * event_groups.h * @code{c} * void xEventGroupDelete( EventGroupHandle_t xEventGroup ); * @endcode * * Delete an event group that was previously created by a call to * xEventGroupCreate(). Tasks that are blocked on the event group will be * unblocked and obtain 0 as the event group's value. * * @param xEventGroup The event group being deleted. */ void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; /* For internal use only. */ void vEventGroupSetBitsCallback( void * pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION; void vEventGroupClearBitsCallback( void * pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION; #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxEventGroupGetNumber( void * xEventGroup ) PRIVILEGED_FUNCTION; void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION; #endif /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* EVENT_GROUPS_H */ ================================================ FILE: FreeRTOS-comparison/include/list.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* * This is the list implementation used by the scheduler. While it is tailored * heavily for the schedulers needs, it is also available for use by * application code. * * list_ts can only store pointers to list_item_ts. Each ListItem_t contains a * numeric value (xItemValue). Most of the time the lists are sorted in * ascending item value order. * * Lists are created already containing one list item. The value of this * item is the maximum possible that can be stored, it is therefore always at * the end of the list and acts as a marker. The list member pxHead always * points to this marker - even though it is at the tail of the list. This * is because the tail contains a wrap back pointer to the true head of * the list. * * In addition to it's value, each list item contains a pointer to the next * item in the list (pxNext), a pointer to the list it is in (pxContainer) * and a pointer to back to the object that contains it. These later two * pointers are included for efficiency of list manipulation. There is * effectively a two way link between the object containing the list item and * the list item itself. * * * \page ListIntroduction List Implementation * \ingroup FreeRTOSIntro */ #ifndef LIST_H #define LIST_H #ifndef INC_FREERTOS_H #error "FreeRTOS.h must be included before list.h" #endif /* * The list structure members are modified from within interrupts, and therefore * by rights should be declared volatile. However, they are only modified in a * functionally atomic way (within critical sections of with the scheduler * suspended) and are either passed by reference into a function or indexed via * a volatile variable. Therefore, in all use cases tested so far, the volatile * qualifier can be omitted in order to provide a moderate performance * improvement without adversely affecting functional behaviour. The assembly * instructions generated by the IAR, ARM and GCC compilers when the respective * compiler's options were set for maximum optimisation has been inspected and * deemed to be as intended. That said, as compiler technology advances, and * especially if aggressive cross module optimisation is used (a use case that * has not been exercised to any great extend) then it is feasible that the * volatile qualifier will be needed for correct optimisation. It is expected * that a compiler removing essential code because, without the volatile * qualifier on the list structure members and with aggressive cross module * optimisation, the compiler deemed the code unnecessary will result in * complete and obvious failure of the scheduler. If this is ever experienced * then the volatile qualifier can be inserted in the relevant places within the * list structures by simply defining configLIST_VOLATILE to volatile in * FreeRTOSConfig.h (as per the example at the bottom of this comment block). * If configLIST_VOLATILE is not defined then the preprocessor directives below * will simply #define configLIST_VOLATILE away completely. * * To use volatile list structure members then add the following line to * FreeRTOSConfig.h (without the quotes): * "#define configLIST_VOLATILE volatile" */ #ifndef configLIST_VOLATILE #define configLIST_VOLATILE #endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */ /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ /* Macros that can be used to place known values within the list structures, * then check that the known values do not get corrupted during the execution of * the application. These may catch the list data structures being overwritten in * memory. They will not catch data errors caused by incorrect configuration or * use of FreeRTOS.*/ #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) /* Define the macros to do nothing. */ #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE #define listFIRST_LIST_INTEGRITY_CHECK_VALUE #define listSECOND_LIST_INTEGRITY_CHECK_VALUE #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) #define listTEST_LIST_INTEGRITY( pxList ) #else /* if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) */ /* Define macros that add new members into the list structures. */ #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1; #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2; #define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1; #define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2; /* Define macros that set the new structure members to known values. */ #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE /* Define macros that will assert if one of the structure members does not * contain its expected value. */ #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) #define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) #endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */ /* * Definition of the only type of object that a list can contain. */ struct xLIST; struct xLIST_ITEM { listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in ascending order. */ struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */ struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */ void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ struct xLIST * configLIST_VOLATILE pxContainer; /*< Pointer to the list in which this list item is placed (if any). */ listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ }; typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */ #if ( configUSE_MINI_LIST_ITEM == 1 ) struct xMINI_LIST_ITEM { listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ configLIST_VOLATILE TickType_t xItemValue; struct xLIST_ITEM * configLIST_VOLATILE pxNext; struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; }; typedef struct xMINI_LIST_ITEM MiniListItem_t; #else typedef struct xLIST_ITEM MiniListItem_t; #endif /* * Definition of the type of queue used by the scheduler. */ typedef struct xLIST { listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ volatile UBaseType_t uxNumberOfItems; ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ } List_t; /* * Access macro to set the owner of a list item. The owner of a list item * is the object (usually a TCB) that contains the list item. * * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER * \ingroup LinkedList */ #define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) ) /* * Access macro to get the owner of a list item. The owner of a list item * is the object (usually a TCB) that contains the list item. * * \page listGET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER * \ingroup LinkedList */ #define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner ) /* * Access macro to set the value of the list item. In most cases the value is * used to sort the list in ascending order. * * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE * \ingroup LinkedList */ #define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) ) /* * Access macro to retrieve the value of the list item. The value can * represent anything - for example the priority of a task, or the time at * which a task should be unblocked. * * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE * \ingroup LinkedList */ #define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue ) /* * Access macro to retrieve the value of the list item at the head of a given * list. * * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE * \ingroup LinkedList */ #define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue ) /* * Return the list item at the head of the list. * * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY * \ingroup LinkedList */ #define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext ) /* * Return the next list item. * * \page listGET_NEXT listGET_NEXT * \ingroup LinkedList */ #define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext ) /* * Return the list item that marks the end of the list * * \page listGET_END_MARKER listGET_END_MARKER * \ingroup LinkedList */ #define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) ) /* * Access macro to determine if a list contains any items. The macro will * only have the value true if the list is empty. * * \page listLIST_IS_EMPTY listLIST_IS_EMPTY * \ingroup LinkedList */ #define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE ) /* * Access macro to return the number of items in the list. */ #define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems ) /* * Access function to obtain the owner of the next entry in a list. * * The list member pxIndex is used to walk through a list. Calling * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list * and returns that entry's pxOwner parameter. Using multiple calls to this * function it is therefore possible to move through every item contained in * a list. * * The pxOwner parameter of a list item is a pointer to the object that owns * the list item. In the scheduler this is normally a task control block. * The pxOwner parameter effectively creates a two way link between the list * item and its owner. * * @param pxTCB pxTCB is set to the address of the owner of the next list item. * @param pxList The list from which the next item owner is to be returned. * * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY * \ingroup LinkedList */ #define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ { \ List_t * const pxConstList = ( pxList ); \ /* Increment the index to the next item and return the item, ensuring */ \ /* we don't return the marker used at the end of the list. */ \ ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ { \ ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ } \ ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ } /* * Version of uxListRemove() that does not return a value. Provided as a slight * optimisation for xTaskIncrementTick() by being inline. * * Remove an item from a list. The list item has a pointer to the list that * it is in, so only the list item need be passed into the function. * * @param uxListRemove The item to be removed. The item will remove itself from * the list pointed to by it's pxContainer parameter. * * @return The number of items that remain in the list after the list item has * been removed. * * \page listREMOVE_ITEM listREMOVE_ITEM * \ingroup LinkedList */ #define listREMOVE_ITEM( pxItemToRemove ) \ { \ /* The list item knows which list it is in. Obtain the list from the list \ * item. */ \ List_t * const pxList = ( pxItemToRemove )->pxContainer; \ \ ( pxItemToRemove )->pxNext->pxPrevious = ( pxItemToRemove )->pxPrevious; \ ( pxItemToRemove )->pxPrevious->pxNext = ( pxItemToRemove )->pxNext; \ /* Make sure the index is left pointing to a valid item. */ \ if( pxList->pxIndex == ( pxItemToRemove ) ) \ { \ pxList->pxIndex = ( pxItemToRemove )->pxPrevious; \ } \ \ ( pxItemToRemove )->pxContainer = NULL; \ ( pxList->uxNumberOfItems )--; \ } /* * Inline version of vListInsertEnd() to provide slight optimisation for * xTaskIncrementTick(). * * Insert a list item into a list. The item will be inserted in a position * such that it will be the last item within the list returned by multiple * calls to listGET_OWNER_OF_NEXT_ENTRY. * * The list member pxIndex is used to walk through a list. Calling * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list. * Placing an item in a list using vListInsertEnd effectively places the item * in the list position pointed to by pxIndex. This means that every other * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before * the pxIndex parameter again points to the item being inserted. * * @param pxList The list into which the item is to be inserted. * * @param pxNewListItem The list item to be inserted into the list. * * \page listINSERT_END listINSERT_END * \ingroup LinkedList */ #define listINSERT_END( pxList, pxNewListItem ) \ { \ ListItem_t * const pxIndex = ( pxList )->pxIndex; \ \ /* Only effective when configASSERT() is also defined, these tests may catch \ * the list data structures being overwritten in memory. They will not catch \ * data errors caused by incorrect configuration or use of FreeRTOS. */ \ listTEST_LIST_INTEGRITY( ( pxList ) ); \ listTEST_LIST_ITEM_INTEGRITY( ( pxNewListItem ) ); \ \ /* Insert a new list item into ( pxList ), but rather than sort the list, \ * makes the new list item the last item to be removed by a call to \ * listGET_OWNER_OF_NEXT_ENTRY(). */ \ ( pxNewListItem )->pxNext = pxIndex; \ ( pxNewListItem )->pxPrevious = pxIndex->pxPrevious; \ \ pxIndex->pxPrevious->pxNext = ( pxNewListItem ); \ pxIndex->pxPrevious = ( pxNewListItem ); \ \ /* Remember which list the item is in. */ \ ( pxNewListItem )->pxContainer = ( pxList ); \ \ ( ( pxList )->uxNumberOfItems )++; \ } /* * Access function to obtain the owner of the first entry in a list. Lists * are normally sorted in ascending item value order. * * This function returns the pxOwner member of the first item in the list. * The pxOwner parameter of a list item is a pointer to the object that owns * the list item. In the scheduler this is normally a task control block. * The pxOwner parameter effectively creates a two way link between the list * item and its owner. * * @param pxList The list from which the owner of the head item is to be * returned. * * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY * \ingroup LinkedList */ #define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( ( &( ( pxList )->xListEnd ) )->pxNext->pvOwner ) /* * Check to see if a list item is within a list. The list item maintains a * "container" pointer that points to the list it is in. All this macro does * is check to see if the container and the list match. * * @param pxList The list we want to know if the list item is within. * @param pxListItem The list item we want to know if is in the list. * @return pdTRUE if the list item is in the list, otherwise pdFALSE. */ #define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) ) /* * Return the list a list item is contained within (referenced from). * * @param pxListItem The list item being queried. * @return A pointer to the List_t object that references the pxListItem */ #define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer ) /* * This provides a crude means of knowing if a list has been initialised, as * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise() * function. */ #define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY ) /* * Must be called before a list is used! This initialises all the members * of the list structure and inserts the xListEnd item into the list as a * marker to the back of the list. * * @param pxList Pointer to the list being initialised. * * \page vListInitialise vListInitialise * \ingroup LinkedList */ void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION; /* * Must be called before a list item is used. This sets the list container to * null so the item does not think that it is already contained in a list. * * @param pxItem Pointer to the list item being initialised. * * \page vListInitialiseItem vListInitialiseItem * \ingroup LinkedList */ void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION; /* * Insert a list item into a list. The item will be inserted into the list in * a position determined by its item value (ascending item value order). * * @param pxList The list into which the item is to be inserted. * * @param pxNewListItem The item that is to be placed in the list. * * \page vListInsert vListInsert * \ingroup LinkedList */ void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; /* * Insert a list item into a list. The item will be inserted in a position * such that it will be the last item within the list returned by multiple * calls to listGET_OWNER_OF_NEXT_ENTRY. * * The list member pxIndex is used to walk through a list. Calling * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list. * Placing an item in a list using vListInsertEnd effectively places the item * in the list position pointed to by pxIndex. This means that every other * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before * the pxIndex parameter again points to the item being inserted. * * @param pxList The list into which the item is to be inserted. * * @param pxNewListItem The list item to be inserted into the list. * * \page vListInsertEnd vListInsertEnd * \ingroup LinkedList */ void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; /* * Remove an item from a list. The list item has a pointer to the list that * it is in, so only the list item need be passed into the function. * * @param uxListRemove The item to be removed. The item will remove itself from * the list pointed to by it's pxContainer parameter. * * @return The number of items that remain in the list after the list item has * been removed. * * \page uxListRemove uxListRemove * \ingroup LinkedList */ UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION; /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* ifndef LIST_H */ ================================================ FILE: FreeRTOS-comparison/include/message_buffer.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* * Message buffers build functionality on top of FreeRTOS stream buffers. * Whereas stream buffers are used to send a continuous stream of data from one * task or interrupt to another, message buffers are used to send variable * length discrete messages from one task or interrupt to another. Their * implementation is light weight, making them particularly suited for interrupt * to task and core to core communication scenarios. * * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer * implementation (so also the message buffer implementation, as message buffers * are built on top of stream buffers) assumes there is only one task or * interrupt that will write to the buffer (the writer), and only one task or * interrupt that will read from the buffer (the reader). It is safe for the * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers * then the application writer must place each call to a writing API function * (such as xMessageBufferSend()) inside a critical section and set the send * block time to 0. Likewise, if there are to be multiple different readers * then the application writer must place each call to a reading API function * (such as xMessageBufferRead()) inside a critical section and set the receive * timeout to 0. * * Message buffers hold variable length messages. To enable that, when a * message is written to the message buffer an additional sizeof( size_t ) bytes * are also written to store the message's length (that happens internally, with * the API function). sizeof( size_t ) is typically 4 bytes on a 32-bit * architecture, so writing a 10 byte message to a message buffer on a 32-bit * architecture will actually reduce the available space in the message buffer * by 14 bytes (10 byte are used by the message, and 4 bytes to hold the length * of the message). */ #ifndef FREERTOS_MESSAGE_BUFFER_H #define FREERTOS_MESSAGE_BUFFER_H #ifndef INC_FREERTOS_H #error "include FreeRTOS.h must appear in source files before include message_buffer.h" #endif /* Message buffers are built onto of stream buffers. */ #include "stream_buffer.h" /* *INDENT-OFF* */ #if defined( __cplusplus ) extern "C" { #endif /* *INDENT-ON* */ /** * Type by which message buffers are referenced. For example, a call to * xMessageBufferCreate() returns an MessageBufferHandle_t variable that can * then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(), * etc. Message buffer is essentially built as a stream buffer hence its handle * is also set to same type as a stream buffer handle. */ typedef StreamBufferHandle_t MessageBufferHandle_t; /*-----------------------------------------------------------*/ /** * message_buffer.h * * @code{c} * MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes ); * @endcode * * Creates a new message buffer using dynamically allocated memory. See * xMessageBufferCreateStatic() for a version that uses statically allocated * memory (memory that is allocated at compile time). * * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in * FreeRTOSConfig.h for xMessageBufferCreate() to be available. * * @param xBufferSizeBytes The total number of bytes (not messages) the message * buffer will be able to hold at any one time. When a message is written to * the message buffer an additional sizeof( size_t ) bytes are also written to * store the message's length. sizeof( size_t ) is typically 4 bytes on a * 32-bit architecture, so on most 32-bit architectures a 10 byte message will * take up 14 bytes of message buffer space. * * @param pxSendCompletedCallback Callback invoked when a send operation to the * message buffer is complete. If the parameter is NULL or xMessageBufferCreate() * is called without the parameter, then it will use the default implementation * provided by sbSEND_COMPLETED macro. To enable the callback, * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h. * * @param pxReceiveCompletedCallback Callback invoked when a receive operation from * the message buffer is complete. If the parameter is NULL or xMessageBufferCreate() * is called without the parameter, it will use the default implementation provided * by sbRECEIVE_COMPLETED macro. To enable the callback, * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h. * * @return If NULL is returned, then the message buffer cannot be created * because there is insufficient heap memory available for FreeRTOS to allocate * the message buffer data structures and storage area. A non-NULL value being * returned indicates that the message buffer has been created successfully - * the returned value should be stored as the handle to the created message * buffer. * * Example use: * @code{c} * * void vAFunction( void ) * { * MessageBufferHandle_t xMessageBuffer; * const size_t xMessageBufferSizeBytes = 100; * * // Create a message buffer that can hold 100 bytes. The memory used to hold * // both the message buffer structure and the messages themselves is allocated * // dynamically. Each message added to the buffer consumes an additional 4 * // bytes which are used to hold the length of the message. * xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes ); * * if( xMessageBuffer == NULL ) * { * // There was not enough heap memory space available to create the * // message buffer. * } * else * { * // The message buffer was created successfully and can now be used. * } * * @endcode * \defgroup xMessageBufferCreate xMessageBufferCreate * \ingroup MessageBufferManagement */ #define xMessageBufferCreate( xBufferSizeBytes ) \ xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, pdTRUE, NULL, NULL ) #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define xMessageBufferCreateWithCallback( xBufferSizeBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, pdTRUE, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) #endif /** * message_buffer.h * * @code{c} * MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes, * uint8_t *pucMessageBufferStorageArea, * StaticMessageBuffer_t *pxStaticMessageBuffer ); * @endcode * Creates a new message buffer using statically allocated memory. See * xMessageBufferCreate() for a version that uses dynamically allocated memory. * * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the * pucMessageBufferStorageArea parameter. When a message is written to the * message buffer an additional sizeof( size_t ) bytes are also written to store * the message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit * architecture, so on most 32-bit architecture a 10 byte message will take up * 14 bytes of message buffer space. The maximum number of bytes that can be * stored in the message buffer is actually (xBufferSizeBytes - 1). * * @param pucMessageBufferStorageArea Must point to a uint8_t array that is at * least xBufferSizeBytes big. This is the array to which messages are * copied when they are written to the message buffer. * * @param pxStaticMessageBuffer Must point to a variable of type * StaticMessageBuffer_t, which will be used to hold the message buffer's data * structure. * * @param pxSendCompletedCallback Callback invoked when a new message is sent to the message buffer. * If the parameter is NULL or xMessageBufferCreate() is called without the parameter, then it will use the default * implementation provided by sbSEND_COMPLETED macro. To enable the callback, * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h. * * @param pxReceiveCompletedCallback Callback invoked when a message is read from a * message buffer. If the parameter is NULL or xMessageBufferCreate() is called without the parameter, it will * use the default implementation provided by sbRECEIVE_COMPLETED macro. To enable the callback, * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h. * * @return If the message buffer is created successfully then a handle to the * created message buffer is returned. If either pucMessageBufferStorageArea or * pxStaticmessageBuffer are NULL then NULL is returned. * * Example use: * @code{c} * * // Used to dimension the array used to hold the messages. The available space * // will actually be one less than this, so 999. #define STORAGE_SIZE_BYTES 1000 * * // Defines the memory that will actually hold the messages within the message * // buffer. * static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ]; * * // The variable used to hold the message buffer structure. * StaticMessageBuffer_t xMessageBufferStruct; * * void MyFunction( void ) * { * MessageBufferHandle_t xMessageBuffer; * * xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucStorageBuffer ), * ucStorageBuffer, * &xMessageBufferStruct ); * * // As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer * // parameters were NULL, xMessageBuffer will not be NULL, and can be used to * // reference the created message buffer in other message buffer API calls. * * // Other code that uses the message buffer can go here. * } * * @endcode * \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic * \ingroup MessageBufferManagement */ #define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) \ xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, pdTRUE, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), NULL, NULL ) #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define xMessageBufferCreateStaticWithCallback( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, pdTRUE, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) #endif /** * message_buffer.h * * @code{c} * size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer, * const void *pvTxData, * size_t xDataLengthBytes, * TickType_t xTicksToWait ); * @endcode * * Sends a discrete message to the message buffer. The message can be any * length that fits within the buffer's free space, and is copied into the * buffer. * * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer * implementation (so also the message buffer implementation, as message buffers * are built on top of stream buffers) assumes there is only one task or * interrupt that will write to the buffer (the writer), and only one task or * interrupt that will read from the buffer (the reader). It is safe for the * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers * then the application writer must place each call to a writing API function * (such as xMessageBufferSend()) inside a critical section and set the send * block time to 0. Likewise, if there are to be multiple different readers * then the application writer must place each call to a reading API function * (such as xMessageBufferRead()) inside a critical section and set the receive * block time to 0. * * Use xMessageBufferSend() to write to a message buffer from a task. Use * xMessageBufferSendFromISR() to write to a message buffer from an interrupt * service routine (ISR). * * @param xMessageBuffer The handle of the message buffer to which a message is * being sent. * * @param pvTxData A pointer to the message that is to be copied into the * message buffer. * * @param xDataLengthBytes The length of the message. That is, the number of * bytes to copy from pvTxData into the message buffer. When a message is * written to the message buffer an additional sizeof( size_t ) bytes are also * written to store the message's length. sizeof( size_t ) is typically 4 bytes * on a 32-bit architecture, so on most 32-bit architecture setting * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24 * bytes (20 bytes of message data and 4 bytes to hold the message length). * * @param xTicksToWait The maximum amount of time the calling task should remain * in the Blocked state to wait for enough space to become available in the * message buffer, should the message buffer have insufficient space when * xMessageBufferSend() is called. The calling task will never block if * xTicksToWait is zero. The block time is specified in tick periods, so the * absolute time it represents is dependent on the tick frequency. The macro * pdMS_TO_TICKS() can be used to convert a time specified in milliseconds into * a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will cause * the task to wait indefinitely (without timing out), provided * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any * CPU time when they are in the Blocked state. * * @return The number of bytes written to the message buffer. If the call to * xMessageBufferSend() times out before there was enough space to write the * message into the message buffer then zero is returned. If the call did not * time out then xDataLengthBytes is returned. * * Example use: * @code{c} * void vAFunction( MessageBufferHandle_t xMessageBuffer ) * { * size_t xBytesSent; * uint8_t ucArrayToSend[] = { 0, 1, 2, 3 }; * char *pcStringToSend = "String to send"; * const TickType_t x100ms = pdMS_TO_TICKS( 100 ); * * // Send an array to the message buffer, blocking for a maximum of 100ms to * // wait for enough space to be available in the message buffer. * xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms ); * * if( xBytesSent != sizeof( ucArrayToSend ) ) * { * // The call to xMessageBufferSend() times out before there was enough * // space in the buffer for the data to be written. * } * * // Send the string to the message buffer. Return immediately if there is * // not enough space in the buffer. * xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 ); * * if( xBytesSent != strlen( pcStringToSend ) ) * { * // The string could not be added to the message buffer because there was * // not enough free space in the buffer. * } * } * @endcode * \defgroup xMessageBufferSend xMessageBufferSend * \ingroup MessageBufferManagement */ #define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) \ xStreamBufferSend( ( xMessageBuffer ), ( pvTxData ), ( xDataLengthBytes ), ( xTicksToWait ) ) /** * message_buffer.h * * @code{c} * size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer, * const void *pvTxData, * size_t xDataLengthBytes, * BaseType_t *pxHigherPriorityTaskWoken ); * @endcode * * Interrupt safe version of the API function that sends a discrete message to * the message buffer. The message can be any length that fits within the * buffer's free space, and is copied into the buffer. * * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer * implementation (so also the message buffer implementation, as message buffers * are built on top of stream buffers) assumes there is only one task or * interrupt that will write to the buffer (the writer), and only one task or * interrupt that will read from the buffer (the reader). It is safe for the * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers * then the application writer must place each call to a writing API function * (such as xMessageBufferSend()) inside a critical section and set the send * block time to 0. Likewise, if there are to be multiple different readers * then the application writer must place each call to a reading API function * (such as xMessageBufferRead()) inside a critical section and set the receive * block time to 0. * * Use xMessageBufferSend() to write to a message buffer from a task. Use * xMessageBufferSendFromISR() to write to a message buffer from an interrupt * service routine (ISR). * * @param xMessageBuffer The handle of the message buffer to which a message is * being sent. * * @param pvTxData A pointer to the message that is to be copied into the * message buffer. * * @param xDataLengthBytes The length of the message. That is, the number of * bytes to copy from pvTxData into the message buffer. When a message is * written to the message buffer an additional sizeof( size_t ) bytes are also * written to store the message's length. sizeof( size_t ) is typically 4 bytes * on a 32-bit architecture, so on most 32-bit architecture setting * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24 * bytes (20 bytes of message data and 4 bytes to hold the message length). * * @param pxHigherPriorityTaskWoken It is possible that a message buffer will * have a task blocked on it waiting for data. Calling * xMessageBufferSendFromISR() can make data available, and so cause a task that * was waiting for data to leave the Blocked state. If calling * xMessageBufferSendFromISR() causes a task to leave the Blocked state, and the * unblocked task has a priority higher than the currently executing task (the * task that was interrupted), then, internally, xMessageBufferSendFromISR() * will set *pxHigherPriorityTaskWoken to pdTRUE. If * xMessageBufferSendFromISR() sets this value to pdTRUE, then normally a * context switch should be performed before the interrupt is exited. This will * ensure that the interrupt returns directly to the highest priority Ready * state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it * is passed into the function. See the code example below for an example. * * @return The number of bytes actually written to the message buffer. If the * message buffer didn't have enough free space for the message to be stored * then 0 is returned, otherwise xDataLengthBytes is returned. * * Example use: * @code{c} * // A message buffer that has already been created. * MessageBufferHandle_t xMessageBuffer; * * void vAnInterruptServiceRoutine( void ) * { * size_t xBytesSent; * char *pcStringToSend = "String to send"; * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. * * // Attempt to send the string to the message buffer. * xBytesSent = xMessageBufferSendFromISR( xMessageBuffer, * ( void * ) pcStringToSend, * strlen( pcStringToSend ), * &xHigherPriorityTaskWoken ); * * if( xBytesSent != strlen( pcStringToSend ) ) * { * // The string could not be added to the message buffer because there was * // not enough free space in the buffer. * } * * // If xHigherPriorityTaskWoken was set to pdTRUE inside * // xMessageBufferSendFromISR() then a task that has a priority above the * // priority of the currently executing task was unblocked and a context * // switch should be performed to ensure the ISR returns to the unblocked * // task. In most FreeRTOS ports this is done by simply passing * // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the * // variables value, and perform the context switch if necessary. Check the * // documentation for the port in use for port specific instructions. * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * } * @endcode * \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR * \ingroup MessageBufferManagement */ #define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) \ xStreamBufferSendFromISR( ( xMessageBuffer ), ( pvTxData ), ( xDataLengthBytes ), ( pxHigherPriorityTaskWoken ) ) /** * message_buffer.h * * @code{c} * size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer, * void *pvRxData, * size_t xBufferLengthBytes, * TickType_t xTicksToWait ); * @endcode * * Receives a discrete message from a message buffer. Messages can be of * variable length and are copied out of the buffer. * * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer * implementation (so also the message buffer implementation, as message buffers * are built on top of stream buffers) assumes there is only one task or * interrupt that will write to the buffer (the writer), and only one task or * interrupt that will read from the buffer (the reader). It is safe for the * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers * then the application writer must place each call to a writing API function * (such as xMessageBufferSend()) inside a critical section and set the send * block time to 0. Likewise, if there are to be multiple different readers * then the application writer must place each call to a reading API function * (such as xMessageBufferRead()) inside a critical section and set the receive * block time to 0. * * Use xMessageBufferReceive() to read from a message buffer from a task. Use * xMessageBufferReceiveFromISR() to read from a message buffer from an * interrupt service routine (ISR). * * @param xMessageBuffer The handle of the message buffer from which a message * is being received. * * @param pvRxData A pointer to the buffer into which the received message is * to be copied. * * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData * parameter. This sets the maximum length of the message that can be received. * If xBufferLengthBytes is too small to hold the next message then the message * will be left in the message buffer and 0 will be returned. * * @param xTicksToWait The maximum amount of time the task should remain in the * Blocked state to wait for a message, should the message buffer be empty. * xMessageBufferReceive() will return immediately if xTicksToWait is zero and * the message buffer is empty. The block time is specified in tick periods, so * the absolute time it represents is dependent on the tick frequency. The * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds * into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will * cause the task to wait indefinitely (without timing out), provided * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any * CPU time when they are in the Blocked state. * * @return The length, in bytes, of the message read from the message buffer, if * any. If xMessageBufferReceive() times out before a message became available * then zero is returned. If the length of the message is greater than * xBufferLengthBytes then the message will be left in the message buffer and * zero is returned. * * Example use: * @code{c} * void vAFunction( MessageBuffer_t xMessageBuffer ) * { * uint8_t ucRxData[ 20 ]; * size_t xReceivedBytes; * const TickType_t xBlockTime = pdMS_TO_TICKS( 20 ); * * // Receive the next message from the message buffer. Wait in the Blocked * // state (so not using any CPU processing time) for a maximum of 100ms for * // a message to become available. * xReceivedBytes = xMessageBufferReceive( xMessageBuffer, * ( void * ) ucRxData, * sizeof( ucRxData ), * xBlockTime ); * * if( xReceivedBytes > 0 ) * { * // A ucRxData contains a message that is xReceivedBytes long. Process * // the message here.... * } * } * @endcode * \defgroup xMessageBufferReceive xMessageBufferReceive * \ingroup MessageBufferManagement */ #define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) \ xStreamBufferReceive( ( xMessageBuffer ), ( pvRxData ), ( xBufferLengthBytes ), ( xTicksToWait ) ) /** * message_buffer.h * * @code{c} * size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer, * void *pvRxData, * size_t xBufferLengthBytes, * BaseType_t *pxHigherPriorityTaskWoken ); * @endcode * * An interrupt safe version of the API function that receives a discrete * message from a message buffer. Messages can be of variable length and are * copied out of the buffer. * * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer * implementation (so also the message buffer implementation, as message buffers * are built on top of stream buffers) assumes there is only one task or * interrupt that will write to the buffer (the writer), and only one task or * interrupt that will read from the buffer (the reader). It is safe for the * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers * then the application writer must place each call to a writing API function * (such as xMessageBufferSend()) inside a critical section and set the send * block time to 0. Likewise, if there are to be multiple different readers * then the application writer must place each call to a reading API function * (such as xMessageBufferRead()) inside a critical section and set the receive * block time to 0. * * Use xMessageBufferReceive() to read from a message buffer from a task. Use * xMessageBufferReceiveFromISR() to read from a message buffer from an * interrupt service routine (ISR). * * @param xMessageBuffer The handle of the message buffer from which a message * is being received. * * @param pvRxData A pointer to the buffer into which the received message is * to be copied. * * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData * parameter. This sets the maximum length of the message that can be received. * If xBufferLengthBytes is too small to hold the next message then the message * will be left in the message buffer and 0 will be returned. * * @param pxHigherPriorityTaskWoken It is possible that a message buffer will * have a task blocked on it waiting for space to become available. Calling * xMessageBufferReceiveFromISR() can make space available, and so cause a task * that is waiting for space to leave the Blocked state. If calling * xMessageBufferReceiveFromISR() causes a task to leave the Blocked state, and * the unblocked task has a priority higher than the currently executing task * (the task that was interrupted), then, internally, * xMessageBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE. * If xMessageBufferReceiveFromISR() sets this value to pdTRUE, then normally a * context switch should be performed before the interrupt is exited. That will * ensure the interrupt returns directly to the highest priority Ready state * task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is * passed into the function. See the code example below for an example. * * @return The length, in bytes, of the message read from the message buffer, if * any. * * Example use: * @code{c} * // A message buffer that has already been created. * MessageBuffer_t xMessageBuffer; * * void vAnInterruptServiceRoutine( void ) * { * uint8_t ucRxData[ 20 ]; * size_t xReceivedBytes; * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. * * // Receive the next message from the message buffer. * xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer, * ( void * ) ucRxData, * sizeof( ucRxData ), * &xHigherPriorityTaskWoken ); * * if( xReceivedBytes > 0 ) * { * // A ucRxData contains a message that is xReceivedBytes long. Process * // the message here.... * } * * // If xHigherPriorityTaskWoken was set to pdTRUE inside * // xMessageBufferReceiveFromISR() then a task that has a priority above the * // priority of the currently executing task was unblocked and a context * // switch should be performed to ensure the ISR returns to the unblocked * // task. In most FreeRTOS ports this is done by simply passing * // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the * // variables value, and perform the context switch if necessary. Check the * // documentation for the port in use for port specific instructions. * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * } * @endcode * \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR * \ingroup MessageBufferManagement */ #define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) \ xStreamBufferReceiveFromISR( ( xMessageBuffer ), ( pvRxData ), ( xBufferLengthBytes ), ( pxHigherPriorityTaskWoken ) ) /** * message_buffer.h * * @code{c} * void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer ); * @endcode * * Deletes a message buffer that was previously created using a call to * xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message * buffer was created using dynamic memory (that is, by xMessageBufferCreate()), * then the allocated memory is freed. * * A message buffer handle must not be used after the message buffer has been * deleted. * * @param xMessageBuffer The handle of the message buffer to be deleted. * */ #define vMessageBufferDelete( xMessageBuffer ) \ vStreamBufferDelete( xMessageBuffer ) /** * message_buffer.h * @code{c} * BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ); * @endcode * * Tests to see if a message buffer is full. A message buffer is full if it * cannot accept any more messages, of any size, until space is made available * by a message being removed from the message buffer. * * @param xMessageBuffer The handle of the message buffer being queried. * * @return If the message buffer referenced by xMessageBuffer is full then * pdTRUE is returned. Otherwise pdFALSE is returned. */ #define xMessageBufferIsFull( xMessageBuffer ) \ xStreamBufferIsFull( xMessageBuffer ) /** * message_buffer.h * @code{c} * BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ); * @endcode * * Tests to see if a message buffer is empty (does not contain any messages). * * @param xMessageBuffer The handle of the message buffer being queried. * * @return If the message buffer referenced by xMessageBuffer is empty then * pdTRUE is returned. Otherwise pdFALSE is returned. * */ #define xMessageBufferIsEmpty( xMessageBuffer ) \ xStreamBufferIsEmpty( xMessageBuffer ) /** * message_buffer.h * @code{c} * BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer ); * @endcode * * Resets a message buffer to its initial empty state, discarding any message it * contained. * * A message buffer can only be reset if there are no tasks blocked on it. * * @param xMessageBuffer The handle of the message buffer being reset. * * @return If the message buffer was reset then pdPASS is returned. If the * message buffer could not be reset because either there was a task blocked on * the message queue to wait for space to become available, or to wait for a * a message to be available, then pdFAIL is returned. * * \defgroup xMessageBufferReset xMessageBufferReset * \ingroup MessageBufferManagement */ #define xMessageBufferReset( xMessageBuffer ) \ xStreamBufferReset( xMessageBuffer ) /** * message_buffer.h * @code{c} * size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ); * @endcode * Returns the number of bytes of free space in the message buffer. * * @param xMessageBuffer The handle of the message buffer being queried. * * @return The number of bytes that can be written to the message buffer before * the message buffer would be full. When a message is written to the message * buffer an additional sizeof( size_t ) bytes are also written to store the * message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit * architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size * of the largest message that can be written to the message buffer is 6 bytes. * * \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable * \ingroup MessageBufferManagement */ #define xMessageBufferSpaceAvailable( xMessageBuffer ) \ xStreamBufferSpacesAvailable( xMessageBuffer ) #define xMessageBufferSpacesAvailable( xMessageBuffer ) \ xStreamBufferSpacesAvailable( xMessageBuffer ) /* Corrects typo in original macro name. */ /** * message_buffer.h * @code{c} * size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ); * @endcode * Returns the length (in bytes) of the next message in a message buffer. * Useful if xMessageBufferReceive() returned 0 because the size of the buffer * passed into xMessageBufferReceive() was too small to hold the next message. * * @param xMessageBuffer The handle of the message buffer being queried. * * @return The length (in bytes) of the next message in the message buffer, or 0 * if the message buffer is empty. * * \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes * \ingroup MessageBufferManagement */ #define xMessageBufferNextLengthBytes( xMessageBuffer ) \ xStreamBufferNextMessageLengthBytes( xMessageBuffer ) PRIVILEGED_FUNCTION; /** * message_buffer.h * * @code{c} * BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xMessageBuffer, BaseType_t *pxHigherPriorityTaskWoken ); * @endcode * * For advanced users only. * * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when * data is sent to a message buffer or stream buffer. If there was a task that * was blocked on the message or stream buffer waiting for data to arrive then * the sbSEND_COMPLETED() macro sends a notification to the task to remove it * from the Blocked state. xMessageBufferSendCompletedFromISR() does the same * thing. It is provided to enable application writers to implement their own * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME. * * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for * additional information. * * @param xMessageBuffer The handle of the stream buffer to which data was * written. * * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be * initialised to pdFALSE before it is passed into * xMessageBufferSendCompletedFromISR(). If calling * xMessageBufferSendCompletedFromISR() removes a task from the Blocked state, * and the task has a priority above the priority of the currently running task, * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a * context switch should be performed before exiting the ISR. * * @return If a task was removed from the Blocked state then pdTRUE is returned. * Otherwise pdFALSE is returned. * * \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR * \ingroup StreamBufferManagement */ #define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) \ xStreamBufferSendCompletedFromISR( ( xMessageBuffer ), ( pxHigherPriorityTaskWoken ) ) /** * message_buffer.h * * @code{c} * BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xMessageBuffer, BaseType_t *pxHigherPriorityTaskWoken ); * @endcode * * For advanced users only. * * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when * data is read out of a message buffer or stream buffer. If there was a task * that was blocked on the message or stream buffer waiting for data to arrive * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to * remove it from the Blocked state. xMessageBufferReceiveCompletedFromISR() * does the same thing. It is provided to enable application writers to * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT * ANY OTHER TIME. * * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for * additional information. * * @param xMessageBuffer The handle of the stream buffer from which data was * read. * * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be * initialised to pdFALSE before it is passed into * xMessageBufferReceiveCompletedFromISR(). If calling * xMessageBufferReceiveCompletedFromISR() removes a task from the Blocked state, * and the task has a priority above the priority of the currently running task, * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a * context switch should be performed before exiting the ISR. * * @return If a task was removed from the Blocked state then pdTRUE is returned. * Otherwise pdFALSE is returned. * * \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR * \ingroup StreamBufferManagement */ #define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) \ xStreamBufferReceiveCompletedFromISR( ( xMessageBuffer ), ( pxHigherPriorityTaskWoken ) ) /* *INDENT-OFF* */ #if defined( __cplusplus ) } /* extern "C" */ #endif /* *INDENT-ON* */ #endif /* !defined( FREERTOS_MESSAGE_BUFFER_H ) */ ================================================ FILE: FreeRTOS-comparison/include/mpu_prototypes.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* * When the MPU is used the standard (non MPU) API functions are mapped to * equivalents that start "MPU_", the prototypes for which are defined in this * header files. This will cause the application code to call the MPU_ version * which wraps the non-MPU version with privilege promoting then demoting code, * so the kernel code always runs will full privileges. */ #ifndef MPU_PROTOTYPES_H #define MPU_PROTOTYPES_H /* MPU versions of task.h API functions. */ BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL; void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL; void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t * pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) FREERTOS_SYSTEM_CALL; void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL; void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL; void MPU_vTaskStartScheduler( void ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSuspendAll( void ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskResumeAll( void ) FREERTOS_SYSTEM_CALL; TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL; char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL; TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void * pvValue ) FREERTOS_SYSTEM_CALL; void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void * pvParameter ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL; configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL; configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) FREERTOS_SYSTEM_CALL; void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL; void MPU_vTaskGetRunTimeStats( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t * pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t * pulNotificationValue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear ) FREERTOS_SYSTEM_CALL; uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL; void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) FREERTOS_SYSTEM_CALL; /* MPU versions of queue.h API functions. */ BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL; QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL; QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL; void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char * pcName ) FREERTOS_SYSTEM_CALL; void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t * pucQueueStorage, StaticQueue_t * pxStaticQueue, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL; void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; /* MPU versions of timers.h API functions. */ TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) FREERTOS_SYSTEM_CALL; TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t * pxTimerBuffer ) FREERTOS_SYSTEM_CALL; void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void * pvNewID ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void * pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; /* MPU versions of event_group.h API functions. */ EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL; EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL; EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL; EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL; EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) FREERTOS_SYSTEM_CALL; /* MPU versions of message/stream_buffer.h API functions. */ size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void * pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void * pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL; StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) FREERTOS_SYSTEM_CALL; StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) FREERTOS_SYSTEM_CALL; #endif /* MPU_PROTOTYPES_H */ ================================================ FILE: FreeRTOS-comparison/include/mpu_wrappers.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef MPU_WRAPPERS_H #define MPU_WRAPPERS_H /* This file redefines API functions to be called through a wrapper macro, but * only for ports that are using the MPU. */ #if ( portUSING_MPU_WRAPPERS == 1 ) /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is * included from queue.c or task.c to prevent it from having an effect within * those files. */ #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* * Map standard (non MPU) API functions to equivalents that start * "MPU_". This will cause the application code to call the MPU_ * version, which wraps the non-MPU version with privilege promoting * then demoting code, so the kernel code always runs will full * privileges. */ /* Map standard task.h API functions to the MPU equivalents. */ #define xTaskCreate MPU_xTaskCreate #define xTaskCreateStatic MPU_xTaskCreateStatic #define vTaskDelete MPU_vTaskDelete #define vTaskDelay MPU_vTaskDelay #define xTaskDelayUntil MPU_xTaskDelayUntil #define xTaskAbortDelay MPU_xTaskAbortDelay #define uxTaskPriorityGet MPU_uxTaskPriorityGet #define eTaskGetState MPU_eTaskGetState #define vTaskGetInfo MPU_vTaskGetInfo #define vTaskPrioritySet MPU_vTaskPrioritySet #define vTaskSuspend MPU_vTaskSuspend #define vTaskResume MPU_vTaskResume #define vTaskSuspendAll MPU_vTaskSuspendAll #define xTaskResumeAll MPU_xTaskResumeAll #define xTaskGetTickCount MPU_xTaskGetTickCount #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks #define pcTaskGetName MPU_pcTaskGetName #define xTaskGetHandle MPU_xTaskGetHandle #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark #define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2 #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer #define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle #define uxTaskGetSystemState MPU_uxTaskGetSystemState #define vTaskList MPU_vTaskList #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats #define ulTaskGetIdleRunTimeCounter MPU_ulTaskGetIdleRunTimeCounter #define ulTaskGetIdleRunTimePercent MPU_ulTaskGetIdleRunTimePercent #define xTaskGenericNotify MPU_xTaskGenericNotify #define xTaskGenericNotifyWait MPU_xTaskGenericNotifyWait #define ulTaskGenericNotifyTake MPU_ulTaskGenericNotifyTake #define xTaskGenericNotifyStateClear MPU_xTaskGenericNotifyStateClear #define ulTaskGenericNotifyValueClear MPU_ulTaskGenericNotifyValueClear #define xTaskCatchUpTicks MPU_xTaskCatchUpTicks #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle #define vTaskSetTimeOutState MPU_vTaskSetTimeOutState #define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState /* Map standard queue.h API functions to the MPU equivalents. */ #define xQueueGenericSend MPU_xQueueGenericSend #define xQueueReceive MPU_xQueueReceive #define xQueuePeek MPU_xQueuePeek #define xQueueSemaphoreTake MPU_xQueueSemaphoreTake #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable #define vQueueDelete MPU_vQueueDelete #define xQueueCreateMutex MPU_xQueueCreateMutex #define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore #define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive #define xQueueGenericCreate MPU_xQueueGenericCreate #define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic #define xQueueCreateSet MPU_xQueueCreateSet #define xQueueAddToSet MPU_xQueueAddToSet #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet #define xQueueSelectFromSet MPU_xQueueSelectFromSet #define xQueueGenericReset MPU_xQueueGenericReset #if ( configQUEUE_REGISTRY_SIZE > 0 ) #define vQueueAddToRegistry MPU_vQueueAddToRegistry #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue #define pcQueueGetName MPU_pcQueueGetName #endif /* Map standard timer.h API functions to the MPU equivalents. */ #define pvTimerGetTimerID MPU_pvTimerGetTimerID #define vTimerSetTimerID MPU_vTimerSetTimerID #define xTimerIsTimerActive MPU_xTimerIsTimerActive #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle #define pcTimerGetName MPU_pcTimerGetName #define vTimerSetReloadMode MPU_vTimerSetReloadMode #define uxTimerGetReloadMode MPU_uxTimerGetReloadMode #define xTimerGetPeriod MPU_xTimerGetPeriod #define xTimerGetExpiryTime MPU_xTimerGetExpiryTime #define xTimerGenericCommand MPU_xTimerGenericCommand /* Map standard event_group.h API functions to the MPU equivalents. */ #define xEventGroupCreate MPU_xEventGroupCreate #define xEventGroupCreateStatic MPU_xEventGroupCreateStatic #define xEventGroupWaitBits MPU_xEventGroupWaitBits #define xEventGroupClearBits MPU_xEventGroupClearBits #define xEventGroupSetBits MPU_xEventGroupSetBits #define xEventGroupSync MPU_xEventGroupSync #define vEventGroupDelete MPU_vEventGroupDelete /* Map standard message/stream_buffer.h API functions to the MPU * equivalents. */ #define xStreamBufferSend MPU_xStreamBufferSend #define xStreamBufferReceive MPU_xStreamBufferReceive #define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes #define vStreamBufferDelete MPU_vStreamBufferDelete #define xStreamBufferIsFull MPU_xStreamBufferIsFull #define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty #define xStreamBufferReset MPU_xStreamBufferReset #define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable #define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable #define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel #define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate #define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic /* Remove the privileged function macro, but keep the PRIVILEGED_DATA * macro so applications can place data in privileged access sections * (useful when using statically allocated objects). */ #define PRIVILEGED_FUNCTION #define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) ) #define FREERTOS_SYSTEM_CALL #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ /* Ensure API functions go in the privileged execution section. */ #define PRIVILEGED_FUNCTION __attribute__( ( section( "privileged_functions" ) ) ) #define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) ) #define FREERTOS_SYSTEM_CALL __attribute__( ( section( "freertos_system_calls" ) ) ) #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ #else /* portUSING_MPU_WRAPPERS */ #define PRIVILEGED_FUNCTION #define PRIVILEGED_DATA #define FREERTOS_SYSTEM_CALL #endif /* portUSING_MPU_WRAPPERS */ #endif /* MPU_WRAPPERS_H */ ================================================ FILE: FreeRTOS-comparison/include/portable.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Portable layer API. Each function must be defined for each port. *----------------------------------------------------------*/ #ifndef PORTABLE_H #define PORTABLE_H /* Each FreeRTOS port has a unique portmacro.h header file. Originally a * pre-processor definition was used to ensure the pre-processor found the correct * portmacro.h file for the port being used. That scheme was deprecated in favour * of setting the compiler's include path such that it found the correct * portmacro.h file - removing the need for the constant and allowing the * portmacro.h file to be located anywhere in relation to the port being used. * Purely for reasons of backward compatibility the old method is still valid, but * to make it clear that new projects should not use it, support for the port * specific constants has been moved into the deprecated_definitions.h header * file. */ #include "deprecated_definitions.h" /* If portENTER_CRITICAL is not defined then including deprecated_definitions.h * did not result in a portmacro.h header file being included - and it should be * included here. In this case the path to the correct portmacro.h header file * must be set in the compiler's include path. */ #ifndef portENTER_CRITICAL #include "portmacro.h" #endif #if portBYTE_ALIGNMENT == 32 #define portBYTE_ALIGNMENT_MASK ( 0x001f ) #elif portBYTE_ALIGNMENT == 16 #define portBYTE_ALIGNMENT_MASK ( 0x000f ) #elif portBYTE_ALIGNMENT == 8 #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) #elif portBYTE_ALIGNMENT == 4 #define portBYTE_ALIGNMENT_MASK ( 0x0003 ) #elif portBYTE_ALIGNMENT == 2 #define portBYTE_ALIGNMENT_MASK ( 0x0001 ) #elif portBYTE_ALIGNMENT == 1 #define portBYTE_ALIGNMENT_MASK ( 0x0000 ) #else /* if portBYTE_ALIGNMENT == 32 */ #error "Invalid portBYTE_ALIGNMENT definition" #endif /* if portBYTE_ALIGNMENT == 32 */ #ifndef portUSING_MPU_WRAPPERS #define portUSING_MPU_WRAPPERS 0 #endif #ifndef portNUM_CONFIGURABLE_REGIONS #define portNUM_CONFIGURABLE_REGIONS 1 #endif #ifndef portHAS_STACK_OVERFLOW_CHECKING #define portHAS_STACK_OVERFLOW_CHECKING 0 #endif #ifndef portARCH_NAME #define portARCH_NAME NULL #endif #ifndef configSTACK_ALLOCATION_FROM_SEPARATE_HEAP /* Defaults to 0 for backward compatibility. */ #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #endif /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ #include "mpu_wrappers.h" /* * Setup the stack of a new task so it is ready to be placed under the * scheduler control. The registers have to be placed on the stack in * the order that the port expects to find them. * */ #if ( portUSING_MPU_WRAPPERS == 1 ) #if ( portHAS_STACK_OVERFLOW_CHECKING == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; #endif #else /* if ( portUSING_MPU_WRAPPERS == 1 ) */ #if ( portHAS_STACK_OVERFLOW_CHECKING == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) PRIVILEGED_FUNCTION; #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) PRIVILEGED_FUNCTION; #endif #endif /* if ( portUSING_MPU_WRAPPERS == 1 ) */ /* Used by heap_5.c to define the start address and size of each memory region * that together comprise the total FreeRTOS heap space. */ typedef struct HeapRegion { uint8_t * pucStartAddress; size_t xSizeInBytes; } HeapRegion_t; /* Used to pass information about the heap out of vPortGetHeapStats(). */ typedef struct xHeapStats { size_t xAvailableHeapSpaceInBytes; /* The total heap size currently available - this is the sum of all the free blocks, not the largest block that can be allocated. */ size_t xSizeOfLargestFreeBlockInBytes; /* The maximum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */ size_t xSizeOfSmallestFreeBlockInBytes; /* The minimum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */ size_t xNumberOfFreeBlocks; /* The number of free memory blocks within the heap at the time vPortGetHeapStats() is called. */ size_t xMinimumEverFreeBytesRemaining; /* The minimum amount of total free memory (sum of all free blocks) there has been in the heap since the system booted. */ size_t xNumberOfSuccessfulAllocations; /* The number of calls to pvPortMalloc() that have returned a valid memory block. */ size_t xNumberOfSuccessfulFrees; /* The number of calls to vPortFree() that has successfully freed a block of memory. */ } HeapStats_t; /* * Used to define multiple heap regions for use by heap_5.c. This function * must be called before any calls to pvPortMalloc() - not creating a task, * queue, semaphore, mutex, software timer, event group, etc. will result in * pvPortMalloc being called. * * pxHeapRegions passes in an array of HeapRegion_t structures - each of which * defines a region of memory that can be used as the heap. The array is * terminated by a HeapRegions_t structure that has a size of 0. The region * with the lowest start address must appear first in the array. */ void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION; /* * Returns a HeapStats_t structure filled with information about the current * heap state. */ void vPortGetHeapStats( HeapStats_t * pxHeapStats ); /* * Map to the memory management routines required for the port. */ void * pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; void * pvPortCalloc( size_t xNum, size_t xSize ) PRIVILEGED_FUNCTION; void vPortFree( void * pv ) PRIVILEGED_FUNCTION; void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; #if ( configSTACK_ALLOCATION_FROM_SEPARATE_HEAP == 1 ) void * pvPortMallocStack( size_t xSize ) PRIVILEGED_FUNCTION; void vPortFreeStack( void * pv ) PRIVILEGED_FUNCTION; #else #define pvPortMallocStack pvPortMalloc #define vPortFreeStack vPortFree #endif #if ( configUSE_MALLOC_FAILED_HOOK == 1 ) /** * task.h * @code{c} * void vApplicationMallocFailedHook( void ) * @endcode * * This hook function is called when allocation failed. */ void vApplicationMallocFailedHook( void ); /*lint !e526 Symbol not defined as it is an application callback. */ #endif /* * Setup the hardware ready for the scheduler to take control. This generally * sets up a tick interrupt and sets timers for the correct tick frequency. */ BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION; /* * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so * the hardware is left in its original condition after the scheduler stops * executing. */ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; /* * The structures and methods of manipulating the MPU are contained within the * port layer. * * Fills the xMPUSettings structure with the memory region information * contained in xRegions. */ #if ( portUSING_MPU_WRAPPERS == 1 ) struct xMEMORY_REGION; void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; #endif /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* PORTABLE_H */ ================================================ FILE: FreeRTOS-comparison/include/projdefs.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PROJDEFS_H #define PROJDEFS_H /* * Defines the prototype to which task functions must conform. Defined in this * file to ensure the type is known before portable.h is included. */ typedef void (* TaskFunction_t)( void * ); /* Converts a time in milliseconds to a time in ticks. This macro can be * overridden by a macro of the same name defined in FreeRTOSConfig.h in case the * definition here is not suitable for your application. */ #ifndef pdMS_TO_TICKS #define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000U ) ) #endif #define pdFALSE ( ( BaseType_t ) 0 ) #define pdTRUE ( ( BaseType_t ) 1 ) #define pdPASS ( pdTRUE ) #define pdFAIL ( pdFALSE ) #define errQUEUE_EMPTY ( ( BaseType_t ) 0 ) #define errQUEUE_FULL ( ( BaseType_t ) 0 ) /* FreeRTOS error definitions. */ #define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) #define errQUEUE_BLOCKED ( -4 ) #define errQUEUE_YIELD ( -5 ) /* Macros used for basic data corruption checks. */ #ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 #endif #if ( configUSE_16_BIT_TICKS == 1 ) #define pdINTEGRITY_CHECK_VALUE 0x5a5a #else #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL #endif /* The following errno values are used by FreeRTOS+ components, not FreeRTOS * itself. */ #define pdFREERTOS_ERRNO_NONE 0 /* No errors */ #define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */ #define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */ #define pdFREERTOS_ERRNO_EIO 5 /* I/O error */ #define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */ #define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */ #define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */ #define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */ #define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */ #define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */ #define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */ #define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */ #define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */ #define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */ #define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */ #define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */ #define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */ #define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */ #define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */ #define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */ #define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */ #define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */ #define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */ #define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */ #define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */ #define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */ #define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */ #define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ #define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ #define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ #define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ #define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */ #define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */ #define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */ #define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */ #define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */ #define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */ #define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */ #define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */ #define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */ /* The following endian values are used by FreeRTOS+ components, not FreeRTOS * itself. */ #define pdFREERTOS_LITTLE_ENDIAN 0 #define pdFREERTOS_BIG_ENDIAN 1 /* Re-defining endian values for generic naming. */ #define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN #define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN #endif /* PROJDEFS_H */ ================================================ FILE: FreeRTOS-comparison/include/queue.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef QUEUE_H #define QUEUE_H #ifndef INC_FREERTOS_H #error "include FreeRTOS.h" must appear in source files before "include queue.h" #endif /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ #include "task.h" /** * Type by which queues are referenced. For example, a call to xQueueCreate() * returns an QueueHandle_t variable that can then be used as a parameter to * xQueueSend(), xQueueReceive(), etc. */ struct QueueDefinition; /* Using old naming convention so as not to break kernel aware debuggers. */ typedef struct QueueDefinition * QueueHandle_t; /** * Type by which queue sets are referenced. For example, a call to * xQueueCreateSet() returns an xQueueSet variable that can then be used as a * parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc. */ typedef struct QueueDefinition * QueueSetHandle_t; /** * Queue sets can contain both queues and semaphores, so the * QueueSetMemberHandle_t is defined as a type to be used where a parameter or * return value can be either an QueueHandle_t or an SemaphoreHandle_t. */ typedef struct QueueDefinition * QueueSetMemberHandle_t; /* For internal use only. */ #define queueSEND_TO_BACK ( ( BaseType_t ) 0 ) #define queueSEND_TO_FRONT ( ( BaseType_t ) 1 ) #define queueOVERWRITE ( ( BaseType_t ) 2 ) /* For internal use only. These definitions *must* match those in queue.c. */ #define queueQUEUE_TYPE_BASE ( ( uint8_t ) 0U ) #define queueQUEUE_TYPE_SET ( ( uint8_t ) 0U ) #define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U ) #define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( uint8_t ) 2U ) #define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U ) #define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( uint8_t ) 4U ) /** * queue. h * @code{c} * QueueHandle_t xQueueCreate( * UBaseType_t uxQueueLength, * UBaseType_t uxItemSize * ); * @endcode * * Creates a new queue instance, and returns a handle by which the new queue * can be referenced. * * Internally, within the FreeRTOS implementation, queues use two blocks of * memory. The first block is used to hold the queue's data structures. The * second block is used to hold items placed into the queue. If a queue is * created using xQueueCreate() then both blocks of memory are automatically * dynamically allocated inside the xQueueCreate() function. (see * https://www.FreeRTOS.org/a00111.html). If a queue is created using * xQueueCreateStatic() then the application writer must provide the memory that * will get used by the queue. xQueueCreateStatic() therefore allows a queue to * be created without using any dynamic memory allocation. * * https://www.FreeRTOS.org/Embedded-RTOS-Queues.html * * @param uxQueueLength The maximum number of items that the queue can contain. * * @param uxItemSize The number of bytes each item in the queue will require. * Items are queued by copy, not by reference, so this is the number of bytes * that will be copied for each posted item. Each item on the queue must be * the same size. * * @return If the queue is successfully create then a handle to the newly * created queue is returned. If the queue cannot be created then 0 is * returned. * * Example usage: * @code{c} * struct AMessage * { * char ucMessageID; * char ucData[ 20 ]; * }; * * void vATask( void *pvParameters ) * { * QueueHandle_t xQueue1, xQueue2; * * // Create a queue capable of containing 10 uint32_t values. * xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) ); * if( xQueue1 == 0 ) * { * // Queue was not created and must not be used. * } * * // Create a queue capable of containing 10 pointers to AMessage structures. * // These should be passed by pointer as they contain a lot of data. * xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) ); * if( xQueue2 == 0 ) * { * // Queue was not created and must not be used. * } * * // ... Rest of task code. * } * @endcode * \defgroup xQueueCreate xQueueCreate * \ingroup QueueManagement */ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) ) #endif /** * queue. h * @code{c} * QueueHandle_t xQueueCreateStatic( * UBaseType_t uxQueueLength, * UBaseType_t uxItemSize, * uint8_t *pucQueueStorage, * StaticQueue_t *pxQueueBuffer * ); * @endcode * * Creates a new queue instance, and returns a handle by which the new queue * can be referenced. * * Internally, within the FreeRTOS implementation, queues use two blocks of * memory. The first block is used to hold the queue's data structures. The * second block is used to hold items placed into the queue. If a queue is * created using xQueueCreate() then both blocks of memory are automatically * dynamically allocated inside the xQueueCreate() function. (see * https://www.FreeRTOS.org/a00111.html). If a queue is created using * xQueueCreateStatic() then the application writer must provide the memory that * will get used by the queue. xQueueCreateStatic() therefore allows a queue to * be created without using any dynamic memory allocation. * * https://www.FreeRTOS.org/Embedded-RTOS-Queues.html * * @param uxQueueLength The maximum number of items that the queue can contain. * * @param uxItemSize The number of bytes each item in the queue will require. * Items are queued by copy, not by reference, so this is the number of bytes * that will be copied for each posted item. Each item on the queue must be * the same size. * * @param pucQueueStorage If uxItemSize is not zero then * pucQueueStorage must point to a uint8_t array that is at least large * enough to hold the maximum number of items that can be in the queue at any * one time - which is ( uxQueueLength * uxItemsSize ) bytes. If uxItemSize is * zero then pucQueueStorage can be NULL. * * @param pxQueueBuffer Must point to a variable of type StaticQueue_t, which * will be used to hold the queue's data structure. * * @return If the queue is created then a handle to the created queue is * returned. If pxQueueBuffer is NULL then NULL is returned. * * Example usage: * @code{c} * struct AMessage * { * char ucMessageID; * char ucData[ 20 ]; * }; * #define QUEUE_LENGTH 10 #define ITEM_SIZE sizeof( uint32_t ) * * // xQueueBuffer will hold the queue structure. * StaticQueue_t xQueueBuffer; * * // ucQueueStorage will hold the items posted to the queue. Must be at least * // [(queue length) * ( queue item size)] bytes long. * uint8_t ucQueueStorage[ QUEUE_LENGTH * ITEM_SIZE ]; * * void vATask( void *pvParameters ) * { * QueueHandle_t xQueue1; * * // Create a queue capable of containing 10 uint32_t values. * xQueue1 = xQueueCreate( QUEUE_LENGTH, // The number of items the queue can hold. * ITEM_SIZE // The size of each item in the queue * &( ucQueueStorage[ 0 ] ), // The buffer that will hold the items in the queue. * &xQueueBuffer ); // The buffer that will hold the queue structure. * * // The queue is guaranteed to be created successfully as no dynamic memory * // allocation is used. Therefore xQueue1 is now a handle to a valid queue. * * // ... Rest of task code. * } * @endcode * \defgroup xQueueCreateStatic xQueueCreateStatic * \ingroup QueueManagement */ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) #define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxQueueBuffer ) xQueueGenericCreateStatic( ( uxQueueLength ), ( uxItemSize ), ( pucQueueStorage ), ( pxQueueBuffer ), ( queueQUEUE_TYPE_BASE ) ) #endif /* configSUPPORT_STATIC_ALLOCATION */ /** * queue. h * @code{c} * BaseType_t xQueueSendToToFront( * QueueHandle_t xQueue, * const void *pvItemToQueue, * TickType_t xTicksToWait * ); * @endcode * * Post an item to the front of a queue. The item is queued by copy, not by * reference. This function must not be called from an interrupt service * routine. See xQueueSendFromISR () for an alternative which may be used * in an ISR. * * @param xQueue The handle to the queue on which the item is to be posted. * * @param pvItemToQueue A pointer to the item that is to be placed on the * queue. The size of the items the queue will hold was defined when the * queue was created, so this many bytes will be copied from pvItemToQueue * into the queue storage area. * * @param xTicksToWait The maximum amount of time the task should block * waiting for space to become available on the queue, should it already * be full. The call will return immediately if this is set to 0 and the * queue is full. The time is defined in tick periods so the constant * portTICK_PERIOD_MS should be used to convert to real time if this is required. * * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. * * Example usage: * @code{c} * struct AMessage * { * char ucMessageID; * char ucData[ 20 ]; * } xMessage; * * uint32_t ulVar = 10UL; * * void vATask( void *pvParameters ) * { * QueueHandle_t xQueue1, xQueue2; * struct AMessage *pxMessage; * * // Create a queue capable of containing 10 uint32_t values. * xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) ); * * // Create a queue capable of containing 10 pointers to AMessage structures. * // These should be passed by pointer as they contain a lot of data. * xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) ); * * // ... * * if( xQueue1 != 0 ) * { * // Send an uint32_t. Wait for 10 ticks for space to become * // available if necessary. * if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS ) * { * // Failed to post the message, even after 10 ticks. * } * } * * if( xQueue2 != 0 ) * { * // Send a pointer to a struct AMessage object. Don't block if the * // queue is already full. * pxMessage = & xMessage; * xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 ); * } * * // ... Rest of task code. * } * @endcode * \defgroup xQueueSend xQueueSend * \ingroup QueueManagement */ #define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) \ xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT ) /** * queue. h * @code{c} * BaseType_t xQueueSendToBack( * QueueHandle_t xQueue, * const void *pvItemToQueue, * TickType_t xTicksToWait * ); * @endcode * * This is a macro that calls xQueueGenericSend(). * * Post an item to the back of a queue. The item is queued by copy, not by * reference. This function must not be called from an interrupt service * routine. See xQueueSendFromISR () for an alternative which may be used * in an ISR. * * @param xQueue The handle to the queue on which the item is to be posted. * * @param pvItemToQueue A pointer to the item that is to be placed on the * queue. The size of the items the queue will hold was defined when the * queue was created, so this many bytes will be copied from pvItemToQueue * into the queue storage area. * * @param xTicksToWait The maximum amount of time the task should block * waiting for space to become available on the queue, should it already * be full. The call will return immediately if this is set to 0 and the queue * is full. The time is defined in tick periods so the constant * portTICK_PERIOD_MS should be used to convert to real time if this is required. * * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. * * Example usage: * @code{c} * struct AMessage * { * char ucMessageID; * char ucData[ 20 ]; * } xMessage; * * uint32_t ulVar = 10UL; * * void vATask( void *pvParameters ) * { * QueueHandle_t xQueue1, xQueue2; * struct AMessage *pxMessage; * * // Create a queue capable of containing 10 uint32_t values. * xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) ); * * // Create a queue capable of containing 10 pointers to AMessage structures. * // These should be passed by pointer as they contain a lot of data. * xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) ); * * // ... * * if( xQueue1 != 0 ) * { * // Send an uint32_t. Wait for 10 ticks for space to become * // available if necessary. * if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS ) * { * // Failed to post the message, even after 10 ticks. * } * } * * if( xQueue2 != 0 ) * { * // Send a pointer to a struct AMessage object. Don't block if the * // queue is already full. * pxMessage = & xMessage; * xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 ); * } * * // ... Rest of task code. * } * @endcode * \defgroup xQueueSend xQueueSend * \ingroup QueueManagement */ #define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) \ xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) /** * queue. h * @code{c} * BaseType_t xQueueSend( * QueueHandle_t xQueue, * const void * pvItemToQueue, * TickType_t xTicksToWait * ); * @endcode * * This is a macro that calls xQueueGenericSend(). It is included for * backward compatibility with versions of FreeRTOS.org that did not * include the xQueueSendToFront() and xQueueSendToBack() macros. It is * equivalent to xQueueSendToBack(). * * Post an item on a queue. The item is queued by copy, not by reference. * This function must not be called from an interrupt service routine. * See xQueueSendFromISR () for an alternative which may be used in an ISR. * * @param xQueue The handle to the queue on which the item is to be posted. * * @param pvItemToQueue A pointer to the item that is to be placed on the * queue. The size of the items the queue will hold was defined when the * queue was created, so this many bytes will be copied from pvItemToQueue * into the queue storage area. * * @param xTicksToWait The maximum amount of time the task should block * waiting for space to become available on the queue, should it already * be full. The call will return immediately if this is set to 0 and the * queue is full. The time is defined in tick periods so the constant * portTICK_PERIOD_MS should be used to convert to real time if this is required. * * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. * * Example usage: * @code{c} * struct AMessage * { * char ucMessageID; * char ucData[ 20 ]; * } xMessage; * * uint32_t ulVar = 10UL; * * void vATask( void *pvParameters ) * { * QueueHandle_t xQueue1, xQueue2; * struct AMessage *pxMessage; * * // Create a queue capable of containing 10 uint32_t values. * xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) ); * * // Create a queue capable of containing 10 pointers to AMessage structures. * // These should be passed by pointer as they contain a lot of data. * xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) ); * * // ... * * if( xQueue1 != 0 ) * { * // Send an uint32_t. Wait for 10 ticks for space to become * // available if necessary. * if( xQueueSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS ) * { * // Failed to post the message, even after 10 ticks. * } * } * * if( xQueue2 != 0 ) * { * // Send a pointer to a struct AMessage object. Don't block if the * // queue is already full. * pxMessage = & xMessage; * xQueueSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 ); * } * * // ... Rest of task code. * } * @endcode * \defgroup xQueueSend xQueueSend * \ingroup QueueManagement */ #define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) \ xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) /** * queue. h * @code{c} * BaseType_t xQueueOverwrite( * QueueHandle_t xQueue, * const void * pvItemToQueue * ); * @endcode * * Only for use with queues that have a length of one - so the queue is either * empty or full. * * Post an item on a queue. If the queue is already full then overwrite the * value held in the queue. The item is queued by copy, not by reference. * * This function must not be called from an interrupt service routine. * See xQueueOverwriteFromISR () for an alternative which may be used in an ISR. * * @param xQueue The handle of the queue to which the data is being sent. * * @param pvItemToQueue A pointer to the item that is to be placed on the * queue. The size of the items the queue will hold was defined when the * queue was created, so this many bytes will be copied from pvItemToQueue * into the queue storage area. * * @return xQueueOverwrite() is a macro that calls xQueueGenericSend(), and * therefore has the same return values as xQueueSendToFront(). However, pdPASS * is the only value that can be returned because xQueueOverwrite() will write * to the queue even when the queue is already full. * * Example usage: * @code{c} * * void vFunction( void *pvParameters ) * { * QueueHandle_t xQueue; * uint32_t ulVarToSend, ulValReceived; * * // Create a queue to hold one uint32_t value. It is strongly * // recommended *not* to use xQueueOverwrite() on queues that can * // contain more than one value, and doing so will trigger an assertion * // if configASSERT() is defined. * xQueue = xQueueCreate( 1, sizeof( uint32_t ) ); * * // Write the value 10 to the queue using xQueueOverwrite(). * ulVarToSend = 10; * xQueueOverwrite( xQueue, &ulVarToSend ); * * // Peeking the queue should now return 10, but leave the value 10 in * // the queue. A block time of zero is used as it is known that the * // queue holds a value. * ulValReceived = 0; * xQueuePeek( xQueue, &ulValReceived, 0 ); * * if( ulValReceived != 10 ) * { * // Error unless the item was removed by a different task. * } * * // The queue is still full. Use xQueueOverwrite() to overwrite the * // value held in the queue with 100. * ulVarToSend = 100; * xQueueOverwrite( xQueue, &ulVarToSend ); * * // This time read from the queue, leaving the queue empty once more. * // A block time of 0 is used again. * xQueueReceive( xQueue, &ulValReceived, 0 ); * * // The value read should be the last value written, even though the * // queue was already full when the value was written. * if( ulValReceived != 100 ) * { * // Error! * } * * // ... * } * @endcode * \defgroup xQueueOverwrite xQueueOverwrite * \ingroup QueueManagement */ #define xQueueOverwrite( xQueue, pvItemToQueue ) \ xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE ) /** * queue. h * @code{c} * BaseType_t xQueueGenericSend( * QueueHandle_t xQueue, * const void * pvItemToQueue, * TickType_t xTicksToWait * BaseType_t xCopyPosition * ); * @endcode * * It is preferred that the macros xQueueSend(), xQueueSendToFront() and * xQueueSendToBack() are used in place of calling this function directly. * * Post an item on a queue. The item is queued by copy, not by reference. * This function must not be called from an interrupt service routine. * See xQueueSendFromISR () for an alternative which may be used in an ISR. * * @param xQueue The handle to the queue on which the item is to be posted. * * @param pvItemToQueue A pointer to the item that is to be placed on the * queue. The size of the items the queue will hold was defined when the * queue was created, so this many bytes will be copied from pvItemToQueue * into the queue storage area. * * @param xTicksToWait The maximum amount of time the task should block * waiting for space to become available on the queue, should it already * be full. The call will return immediately if this is set to 0 and the * queue is full. The time is defined in tick periods so the constant * portTICK_PERIOD_MS should be used to convert to real time if this is required. * * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the * item at the back of the queue, or queueSEND_TO_FRONT to place the item * at the front of the queue (for high priority messages). * * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. * * Example usage: * @code{c} * struct AMessage * { * char ucMessageID; * char ucData[ 20 ]; * } xMessage; * * uint32_t ulVar = 10UL; * * void vATask( void *pvParameters ) * { * QueueHandle_t xQueue1, xQueue2; * struct AMessage *pxMessage; * * // Create a queue capable of containing 10 uint32_t values. * xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) ); * * // Create a queue capable of containing 10 pointers to AMessage structures. * // These should be passed by pointer as they contain a lot of data. * xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) ); * * // ... * * if( xQueue1 != 0 ) * { * // Send an uint32_t. Wait for 10 ticks for space to become * // available if necessary. * if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10, queueSEND_TO_BACK ) != pdPASS ) * { * // Failed to post the message, even after 10 ticks. * } * } * * if( xQueue2 != 0 ) * { * // Send a pointer to a struct AMessage object. Don't block if the * // queue is already full. * pxMessage = & xMessage; * xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0, queueSEND_TO_BACK ); * } * * // ... Rest of task code. * } * @endcode * \defgroup xQueueSend xQueueSend * \ingroup QueueManagement */ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; /** * queue. h * @code{c} * BaseType_t xQueuePeek( * QueueHandle_t xQueue, * void * const pvBuffer, * TickType_t xTicksToWait * ); * @endcode * * Receive an item from a queue without removing the item from the queue. * The item is received by copy so a buffer of adequate size must be * provided. The number of bytes copied into the buffer was defined when * the queue was created. * * Successfully received items remain on the queue so will be returned again * by the next call, or a call to xQueueReceive(). * * This macro must not be used in an interrupt service routine. See * xQueuePeekFromISR() for an alternative that can be called from an interrupt * service routine. * * @param xQueue The handle to the queue from which the item is to be * received. * * @param pvBuffer Pointer to the buffer into which the received item will * be copied. * * @param xTicksToWait The maximum amount of time the task should block * waiting for an item to receive should the queue be empty at the time * of the call. The time is defined in tick periods so the constant * portTICK_PERIOD_MS should be used to convert to real time if this is required. * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue * is empty. * * @return pdTRUE if an item was successfully received from the queue, * otherwise pdFALSE. * * Example usage: * @code{c} * struct AMessage * { * char ucMessageID; * char ucData[ 20 ]; * } xMessage; * * QueueHandle_t xQueue; * * // Task to create a queue and post a value. * void vATask( void *pvParameters ) * { * struct AMessage *pxMessage; * * // Create a queue capable of containing 10 pointers to AMessage structures. * // These should be passed by pointer as they contain a lot of data. * xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) ); * if( xQueue == 0 ) * { * // Failed to create the queue. * } * * // ... * * // Send a pointer to a struct AMessage object. Don't block if the * // queue is already full. * pxMessage = & xMessage; * xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 ); * * // ... Rest of task code. * } * * // Task to peek the data from the queue. * void vADifferentTask( void *pvParameters ) * { * struct AMessage *pxRxedMessage; * * if( xQueue != 0 ) * { * // Peek a message on the created queue. Block for 10 ticks if a * // message is not immediately available. * if( xQueuePeek( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) ) * { * // pcRxedMessage now points to the struct AMessage variable posted * // by vATask, but the item still remains on the queue. * } * } * * // ... Rest of task code. * } * @endcode * \defgroup xQueuePeek xQueuePeek * \ingroup QueueManagement */ BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** * queue. h * @code{c} * BaseType_t xQueuePeekFromISR( * QueueHandle_t xQueue, * void *pvBuffer, * ); * @endcode * * A version of xQueuePeek() that can be called from an interrupt service * routine (ISR). * * Receive an item from a queue without removing the item from the queue. * The item is received by copy so a buffer of adequate size must be * provided. The number of bytes copied into the buffer was defined when * the queue was created. * * Successfully received items remain on the queue so will be returned again * by the next call, or a call to xQueueReceive(). * * @param xQueue The handle to the queue from which the item is to be * received. * * @param pvBuffer Pointer to the buffer into which the received item will * be copied. * * @return pdTRUE if an item was successfully received from the queue, * otherwise pdFALSE. * * \defgroup xQueuePeekFromISR xQueuePeekFromISR * \ingroup QueueManagement */ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION; /** * queue. h * @code{c} * BaseType_t xQueueReceive( * QueueHandle_t xQueue, * void *pvBuffer, * TickType_t xTicksToWait * ); * @endcode * * Receive an item from a queue. The item is received by copy so a buffer of * adequate size must be provided. The number of bytes copied into the buffer * was defined when the queue was created. * * Successfully received items are removed from the queue. * * This function must not be used in an interrupt service routine. See * xQueueReceiveFromISR for an alternative that can. * * @param xQueue The handle to the queue from which the item is to be * received. * * @param pvBuffer Pointer to the buffer into which the received item will * be copied. * * @param xTicksToWait The maximum amount of time the task should block * waiting for an item to receive should the queue be empty at the time * of the call. xQueueReceive() will return immediately if xTicksToWait * is zero and the queue is empty. The time is defined in tick periods so the * constant portTICK_PERIOD_MS should be used to convert to real time if this is * required. * * @return pdTRUE if an item was successfully received from the queue, * otherwise pdFALSE. * * Example usage: * @code{c} * struct AMessage * { * char ucMessageID; * char ucData[ 20 ]; * } xMessage; * * QueueHandle_t xQueue; * * // Task to create a queue and post a value. * void vATask( void *pvParameters ) * { * struct AMessage *pxMessage; * * // Create a queue capable of containing 10 pointers to AMessage structures. * // These should be passed by pointer as they contain a lot of data. * xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) ); * if( xQueue == 0 ) * { * // Failed to create the queue. * } * * // ... * * // Send a pointer to a struct AMessage object. Don't block if the * // queue is already full. * pxMessage = & xMessage; * xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 ); * * // ... Rest of task code. * } * * // Task to receive from the queue. * void vADifferentTask( void *pvParameters ) * { * struct AMessage *pxRxedMessage; * * if( xQueue != 0 ) * { * // Receive a message on the created queue. Block for 10 ticks if a * // message is not immediately available. * if( xQueueReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) ) * { * // pcRxedMessage now points to the struct AMessage variable posted * // by vATask. * } * } * * // ... Rest of task code. * } * @endcode * \defgroup xQueueReceive xQueueReceive * \ingroup QueueManagement */ BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** * queue. h * @code{c} * UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ); * @endcode * * Return the number of messages stored in a queue. * * @param xQueue A handle to the queue being queried. * * @return The number of messages available in the queue. * * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting * \ingroup QueueManagement */ UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /** * queue. h * @code{c} * UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ); * @endcode * * Return the number of free spaces available in a queue. This is equal to the * number of items that can be sent to the queue before the queue becomes full * if no items are removed. * * @param xQueue A handle to the queue being queried. * * @return The number of spaces available in the queue. * * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting * \ingroup QueueManagement */ UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /** * queue. h * @code{c} * void vQueueDelete( QueueHandle_t xQueue ); * @endcode * * Delete a queue - freeing all the memory allocated for storing of items * placed on the queue. * * @param xQueue A handle to the queue to be deleted. * * \defgroup vQueueDelete vQueueDelete * \ingroup QueueManagement */ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /** * queue. h * @code{c} * BaseType_t xQueueSendToFrontFromISR( * QueueHandle_t xQueue, * const void *pvItemToQueue, * BaseType_t *pxHigherPriorityTaskWoken * ); * @endcode * * This is a macro that calls xQueueGenericSendFromISR(). * * Post an item to the front of a queue. It is safe to use this macro from * within an interrupt service routine. * * Items are queued by copy not reference so it is preferable to only * queue small items, especially when called from an ISR. In most cases * it would be preferable to store a pointer to the item being queued. * * @param xQueue The handle to the queue on which the item is to be posted. * * @param pvItemToQueue A pointer to the item that is to be placed on the * queue. The size of the items the queue will hold was defined when the * queue was created, so this many bytes will be copied from pvItemToQueue * into the queue storage area. * * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task * to unblock, and the unblocked task has a priority higher than the currently * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then * a context switch should be requested before the interrupt is exited. * * @return pdTRUE if the data was successfully sent to the queue, otherwise * errQUEUE_FULL. * * Example usage for buffered IO (where the ISR can obtain more than one value * per call): * @code{c} * void vBufferISR( void ) * { * char cIn; * BaseType_t xHigherPriorityTaskWoken; * * // We have not woken a task at the start of the ISR. * xHigherPriorityTaskWoken = pdFALSE; * * // Loop until the buffer is empty. * do * { * // Obtain a byte from the buffer. * cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); * * // Post the byte. * xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken ); * * } while( portINPUT_BYTE( BUFFER_COUNT ) ); * * // Now the buffer is empty we can switch context if necessary. * if( xHigherPriorityTaskWoken ) * { * taskYIELD (); * } * } * @endcode * * \defgroup xQueueSendFromISR xQueueSendFromISR * \ingroup QueueManagement */ #define xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) \ xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT ) /** * queue. h * @code{c} * BaseType_t xQueueSendToBackFromISR( * QueueHandle_t xQueue, * const void *pvItemToQueue, * BaseType_t *pxHigherPriorityTaskWoken * ); * @endcode * * This is a macro that calls xQueueGenericSendFromISR(). * * Post an item to the back of a queue. It is safe to use this macro from * within an interrupt service routine. * * Items are queued by copy not reference so it is preferable to only * queue small items, especially when called from an ISR. In most cases * it would be preferable to store a pointer to the item being queued. * * @param xQueue The handle to the queue on which the item is to be posted. * * @param pvItemToQueue A pointer to the item that is to be placed on the * queue. The size of the items the queue will hold was defined when the * queue was created, so this many bytes will be copied from pvItemToQueue * into the queue storage area. * * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task * to unblock, and the unblocked task has a priority higher than the currently * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then * a context switch should be requested before the interrupt is exited. * * @return pdTRUE if the data was successfully sent to the queue, otherwise * errQUEUE_FULL. * * Example usage for buffered IO (where the ISR can obtain more than one value * per call): * @code{c} * void vBufferISR( void ) * { * char cIn; * BaseType_t xHigherPriorityTaskWoken; * * // We have not woken a task at the start of the ISR. * xHigherPriorityTaskWoken = pdFALSE; * * // Loop until the buffer is empty. * do * { * // Obtain a byte from the buffer. * cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); * * // Post the byte. * xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken ); * * } while( portINPUT_BYTE( BUFFER_COUNT ) ); * * // Now the buffer is empty we can switch context if necessary. * if( xHigherPriorityTaskWoken ) * { * taskYIELD (); * } * } * @endcode * * \defgroup xQueueSendFromISR xQueueSendFromISR * \ingroup QueueManagement */ #define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) \ xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) /** * queue. h * @code{c} * BaseType_t xQueueOverwriteFromISR( * QueueHandle_t xQueue, * const void * pvItemToQueue, * BaseType_t *pxHigherPriorityTaskWoken * ); * @endcode * * A version of xQueueOverwrite() that can be used in an interrupt service * routine (ISR). * * Only for use with queues that can hold a single item - so the queue is either * empty or full. * * Post an item on a queue. If the queue is already full then overwrite the * value held in the queue. The item is queued by copy, not by reference. * * @param xQueue The handle to the queue on which the item is to be posted. * * @param pvItemToQueue A pointer to the item that is to be placed on the * queue. The size of the items the queue will hold was defined when the * queue was created, so this many bytes will be copied from pvItemToQueue * into the queue storage area. * * @param pxHigherPriorityTaskWoken xQueueOverwriteFromISR() will set * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task * to unblock, and the unblocked task has a priority higher than the currently * running task. If xQueueOverwriteFromISR() sets this value to pdTRUE then * a context switch should be requested before the interrupt is exited. * * @return xQueueOverwriteFromISR() is a macro that calls * xQueueGenericSendFromISR(), and therefore has the same return values as * xQueueSendToFrontFromISR(). However, pdPASS is the only value that can be * returned because xQueueOverwriteFromISR() will write to the queue even when * the queue is already full. * * Example usage: * @code{c} * * QueueHandle_t xQueue; * * void vFunction( void *pvParameters ) * { * // Create a queue to hold one uint32_t value. It is strongly * // recommended *not* to use xQueueOverwriteFromISR() on queues that can * // contain more than one value, and doing so will trigger an assertion * // if configASSERT() is defined. * xQueue = xQueueCreate( 1, sizeof( uint32_t ) ); * } * * void vAnInterruptHandler( void ) * { * // xHigherPriorityTaskWoken must be set to pdFALSE before it is used. * BaseType_t xHigherPriorityTaskWoken = pdFALSE; * uint32_t ulVarToSend, ulValReceived; * * // Write the value 10 to the queue using xQueueOverwriteFromISR(). * ulVarToSend = 10; * xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken ); * * // The queue is full, but calling xQueueOverwriteFromISR() again will still * // pass because the value held in the queue will be overwritten with the * // new value. * ulVarToSend = 100; * xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken ); * * // Reading from the queue will now return 100. * * // ... * * if( xHigherPrioritytaskWoken == pdTRUE ) * { * // Writing to the queue caused a task to unblock and the unblocked task * // has a priority higher than or equal to the priority of the currently * // executing task (the task this interrupt interrupted). Perform a context * // switch so this interrupt returns directly to the unblocked task. * portYIELD_FROM_ISR(); // or portEND_SWITCHING_ISR() depending on the port. * } * } * @endcode * \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR * \ingroup QueueManagement */ #define xQueueOverwriteFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) \ xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE ) /** * queue. h * @code{c} * BaseType_t xQueueSendFromISR( * QueueHandle_t xQueue, * const void *pvItemToQueue, * BaseType_t *pxHigherPriorityTaskWoken * ); * @endcode * * This is a macro that calls xQueueGenericSendFromISR(). It is included * for backward compatibility with versions of FreeRTOS.org that did not * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR() * macros. * * Post an item to the back of a queue. It is safe to use this function from * within an interrupt service routine. * * Items are queued by copy not reference so it is preferable to only * queue small items, especially when called from an ISR. In most cases * it would be preferable to store a pointer to the item being queued. * * @param xQueue The handle to the queue on which the item is to be posted. * * @param pvItemToQueue A pointer to the item that is to be placed on the * queue. The size of the items the queue will hold was defined when the * queue was created, so this many bytes will be copied from pvItemToQueue * into the queue storage area. * * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task * to unblock, and the unblocked task has a priority higher than the currently * running task. If xQueueSendFromISR() sets this value to pdTRUE then * a context switch should be requested before the interrupt is exited. * * @return pdTRUE if the data was successfully sent to the queue, otherwise * errQUEUE_FULL. * * Example usage for buffered IO (where the ISR can obtain more than one value * per call): * @code{c} * void vBufferISR( void ) * { * char cIn; * BaseType_t xHigherPriorityTaskWoken; * * // We have not woken a task at the start of the ISR. * xHigherPriorityTaskWoken = pdFALSE; * * // Loop until the buffer is empty. * do * { * // Obtain a byte from the buffer. * cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); * * // Post the byte. * xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken ); * * } while( portINPUT_BYTE( BUFFER_COUNT ) ); * * // Now the buffer is empty we can switch context if necessary. * if( xHigherPriorityTaskWoken ) * { * // Actual macro used here is port specific. * portYIELD_FROM_ISR (); * } * } * @endcode * * \defgroup xQueueSendFromISR xQueueSendFromISR * \ingroup QueueManagement */ #define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) \ xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) /** * queue. h * @code{c} * BaseType_t xQueueGenericSendFromISR( * QueueHandle_t xQueue, * const void *pvItemToQueue, * BaseType_t *pxHigherPriorityTaskWoken, * BaseType_t xCopyPosition * ); * @endcode * * It is preferred that the macros xQueueSendFromISR(), * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place * of calling this function directly. xQueueGiveFromISR() is an * equivalent for use by semaphores that don't actually copy any data. * * Post an item on a queue. It is safe to use this function from within an * interrupt service routine. * * Items are queued by copy not reference so it is preferable to only * queue small items, especially when called from an ISR. In most cases * it would be preferable to store a pointer to the item being queued. * * @param xQueue The handle to the queue on which the item is to be posted. * * @param pvItemToQueue A pointer to the item that is to be placed on the * queue. The size of the items the queue will hold was defined when the * queue was created, so this many bytes will be copied from pvItemToQueue * into the queue storage area. * * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task * to unblock, and the unblocked task has a priority higher than the currently * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then * a context switch should be requested before the interrupt is exited. * * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the * item at the back of the queue, or queueSEND_TO_FRONT to place the item * at the front of the queue (for high priority messages). * * @return pdTRUE if the data was successfully sent to the queue, otherwise * errQUEUE_FULL. * * Example usage for buffered IO (where the ISR can obtain more than one value * per call): * @code{c} * void vBufferISR( void ) * { * char cIn; * BaseType_t xHigherPriorityTaskWokenByPost; * * // We have not woken a task at the start of the ISR. * xHigherPriorityTaskWokenByPost = pdFALSE; * * // Loop until the buffer is empty. * do * { * // Obtain a byte from the buffer. * cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); * * // Post each byte. * xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK ); * * } while( portINPUT_BYTE( BUFFER_COUNT ) ); * * // Now the buffer is empty we can switch context if necessary. Note that the * // name of the yield function required is port specific. * if( xHigherPriorityTaskWokenByPost ) * { * portYIELD_FROM_ISR(); * } * } * @endcode * * \defgroup xQueueSendFromISR xQueueSendFromISR * \ingroup QueueManagement */ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t * const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; /** * queue. h * @code{c} * BaseType_t xQueueReceiveFromISR( * QueueHandle_t xQueue, * void *pvBuffer, * BaseType_t *pxTaskWoken * ); * @endcode * * Receive an item from a queue. It is safe to use this function from within an * interrupt service routine. * * @param xQueue The handle to the queue from which the item is to be * received. * * @param pvBuffer Pointer to the buffer into which the received item will * be copied. * * @param pxTaskWoken A task may be blocked waiting for space to become * available on the queue. If xQueueReceiveFromISR causes such a task to * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will * remain unchanged. * * @return pdTRUE if an item was successfully received from the queue, * otherwise pdFALSE. * * Example usage: * @code{c} * * QueueHandle_t xQueue; * * // Function to create a queue and post some values. * void vAFunction( void *pvParameters ) * { * char cValueToPost; * const TickType_t xTicksToWait = ( TickType_t )0xff; * * // Create a queue capable of containing 10 characters. * xQueue = xQueueCreate( 10, sizeof( char ) ); * if( xQueue == 0 ) * { * // Failed to create the queue. * } * * // ... * * // Post some characters that will be used within an ISR. If the queue * // is full then this task will block for xTicksToWait ticks. * cValueToPost = 'a'; * xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait ); * cValueToPost = 'b'; * xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait ); * * // ... keep posting characters ... this task may block when the queue * // becomes full. * * cValueToPost = 'c'; * xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait ); * } * * // ISR that outputs all the characters received on the queue. * void vISR_Routine( void ) * { * BaseType_t xTaskWokenByReceive = pdFALSE; * char cRxedChar; * * while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) ) * { * // A character was received. Output the character now. * vOutputCharacter( cRxedChar ); * * // If removing the character from the queue woke the task that was * // posting onto the queue xTaskWokenByReceive will have been set to * // pdTRUE. No matter how many times this loop iterates only one * // task will be woken. * } * * if( xTaskWokenByReceive != ( char ) pdFALSE; * { * taskYIELD (); * } * } * @endcode * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR * \ingroup QueueManagement */ BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; /* * Utilities to query queues that are safe to use from an ISR. These utilities * should be used only from within an ISR, or within a critical section. */ BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /* * The functions defined above are for passing data to and from tasks. The * functions below are the equivalents for passing data to and from * co-routines. * * These functions are called from the co-routine macro implementation and * should not be called directly from application code. Instead use the macro * wrappers defined within croutine.h. */ BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t xCoRoutinePreviouslyWoken ); BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, void * pvBuffer, BaseType_t * pxTaskWoken ); BaseType_t xQueueCRSend( QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait ); BaseType_t xQueueCRReceive( QueueHandle_t xQueue, void * pvBuffer, TickType_t xTicksToWait ); /* * For internal use only. Use xSemaphoreCreateMutex(), * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling * these functions directly. */ QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION; QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION; QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION; BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; TaskHandle_t xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; TaskHandle_t xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; /* * For internal use only. Use xSemaphoreTakeMutexRecursive() or * xSemaphoreGiveMutexRecursive() instead of calling these functions directly. */ BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; /* * Reset a queue back to its original empty state. The return value is now * obsolete and is always set to pdPASS. */ #define xQueueReset( xQueue ) xQueueGenericReset( ( xQueue ), pdFALSE ) /* * The registry is provided as a means for kernel aware debuggers to * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add * a queue, semaphore or mutex handle to the registry if you want the handle * to be available to a kernel aware debugger. If you are not using a kernel * aware debugger then this function can be ignored. * * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0 * within FreeRTOSConfig.h for the registry to be available. Its value * does not affect the number of queues, semaphores and mutexes that can be * created - just the number that the registry can hold. * * If vQueueAddToRegistry is called more than once with the same xQueue * parameter, the registry will store the pcQueueName parameter from the * most recent call to vQueueAddToRegistry. * * @param xQueue The handle of the queue being added to the registry. This * is the handle returned by a call to xQueueCreate(). Semaphore and mutex * handles can also be passed in here. * * @param pcQueueName The name to be associated with the handle. This is the * name that the kernel aware debugger will display. The queue registry only * stores a pointer to the string - so the string must be persistent (global or * preferably in ROM/Flash), not on the stack. */ #if ( configQUEUE_REGISTRY_SIZE > 0 ) void vQueueAddToRegistry( QueueHandle_t xQueue, const char * pcQueueName ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ #endif /* * The registry is provided as a means for kernel aware debuggers to * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add * a queue, semaphore or mutex handle to the registry if you want the handle * to be available to a kernel aware debugger, and vQueueUnregisterQueue() to * remove the queue, semaphore or mutex from the register. If you are not using * a kernel aware debugger then this function can be ignored. * * @param xQueue The handle of the queue being removed from the registry. */ #if ( configQUEUE_REGISTRY_SIZE > 0 ) void vQueueUnregisterQueue( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; #endif /* * The queue registry is provided as a means for kernel aware debuggers to * locate queues, semaphores and mutexes. Call pcQueueGetName() to look * up and return the name of a queue in the queue registry from the queue's * handle. * * @param xQueue The handle of the queue the name of which will be returned. * @return If the queue is in the registry then a pointer to the name of the * queue is returned. If the queue is not in the registry then NULL is * returned. */ #if ( configQUEUE_REGISTRY_SIZE > 0 ) const char * pcQueueGetName( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ #endif /* * Generic version of the function used to create a queue using dynamic memory * allocation. This is called by other functions and macros that create other * RTOS objects that use the queue structure as their base. */ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; #endif /* * Generic version of the function used to create a queue using dynamic memory * allocation. This is called by other functions and macros that create other * RTOS objects that use the queue structure as their base. */ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t * pucQueueStorage, StaticQueue_t * pxStaticQueue, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; #endif /* * Queue sets provide a mechanism to allow a task to block (pend) on a read * operation from multiple queues or semaphores simultaneously. * * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this * function. * * A queue set must be explicitly created using a call to xQueueCreateSet() * before it can be used. Once created, standard FreeRTOS queues and semaphores * can be added to the set using calls to xQueueAddToSet(). * xQueueSelectFromSet() is then used to determine which, if any, of the queues * or semaphores contained in the set is in a state where a queue read or * semaphore take operation would be successful. * * Note 1: See the documentation on https://www.FreeRTOS.org/RTOS-queue-sets.html * for reasons why queue sets are very rarely needed in practice as there are * simpler methods of blocking on multiple objects. * * Note 2: Blocking on a queue set that contains a mutex will not cause the * mutex holder to inherit the priority of the blocked task. * * Note 3: An additional 4 bytes of RAM is required for each space in a every * queue added to a queue set. Therefore counting semaphores that have a high * maximum count value should not be added to a queue set. * * Note 4: A receive (in the case of a queue) or take (in the case of a * semaphore) operation must not be performed on a member of a queue set unless * a call to xQueueSelectFromSet() has first returned a handle to that set member. * * @param uxEventQueueLength Queue sets store events that occur on * the queues and semaphores contained in the set. uxEventQueueLength specifies * the maximum number of events that can be queued at once. To be absolutely * certain that events are not lost uxEventQueueLength should be set to the * total sum of the length of the queues added to the set, where binary * semaphores and mutexes have a length of 1, and counting semaphores have a * length set by their maximum count value. Examples: * + If a queue set is to hold a queue of length 5, another queue of length 12, * and a binary semaphore, then uxEventQueueLength should be set to * (5 + 12 + 1), or 18. * + If a queue set is to hold three binary semaphores then uxEventQueueLength * should be set to (1 + 1 + 1 ), or 3. * + If a queue set is to hold a counting semaphore that has a maximum count of * 5, and a counting semaphore that has a maximum count of 3, then * uxEventQueueLength should be set to (5 + 3), or 8. * * @return If the queue set is created successfully then a handle to the created * queue set is returned. Otherwise NULL is returned. */ QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION; /* * Adds a queue or semaphore to a queue set that was previously created by a * call to xQueueCreateSet(). * * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this * function. * * Note 1: A receive (in the case of a queue) or take (in the case of a * semaphore) operation must not be performed on a member of a queue set unless * a call to xQueueSelectFromSet() has first returned a handle to that set member. * * @param xQueueOrSemaphore The handle of the queue or semaphore being added to * the queue set (cast to an QueueSetMemberHandle_t type). * * @param xQueueSet The handle of the queue set to which the queue or semaphore * is being added. * * @return If the queue or semaphore was successfully added to the queue set * then pdPASS is returned. If the queue could not be successfully added to the * queue set because it is already a member of a different queue set then pdFAIL * is returned. */ BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; /* * Removes a queue or semaphore from a queue set. A queue or semaphore can only * be removed from a set if the queue or semaphore is empty. * * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this * function. * * @param xQueueOrSemaphore The handle of the queue or semaphore being removed * from the queue set (cast to an QueueSetMemberHandle_t type). * * @param xQueueSet The handle of the queue set in which the queue or semaphore * is included. * * @return If the queue or semaphore was successfully removed from the queue set * then pdPASS is returned. If the queue was not in the queue set, or the * queue (or semaphore) was not empty, then pdFAIL is returned. */ BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; /* * xQueueSelectFromSet() selects from the members of a queue set a queue or * semaphore that either contains data (in the case of a queue) or is available * to take (in the case of a semaphore). xQueueSelectFromSet() effectively * allows a task to block (pend) on a read operation on all the queues and * semaphores in a queue set simultaneously. * * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this * function. * * Note 1: See the documentation on https://www.FreeRTOS.org/RTOS-queue-sets.html * for reasons why queue sets are very rarely needed in practice as there are * simpler methods of blocking on multiple objects. * * Note 2: Blocking on a queue set that contains a mutex will not cause the * mutex holder to inherit the priority of the blocked task. * * Note 3: A receive (in the case of a queue) or take (in the case of a * semaphore) operation must not be performed on a member of a queue set unless * a call to xQueueSelectFromSet() has first returned a handle to that set member. * * @param xQueueSet The queue set on which the task will (potentially) block. * * @param xTicksToWait The maximum time, in ticks, that the calling task will * remain in the Blocked state (with other tasks executing) to wait for a member * of the queue set to be ready for a successful queue read or semaphore take * operation. * * @return xQueueSelectFromSet() will return the handle of a queue (cast to * a QueueSetMemberHandle_t type) contained in the queue set that contains data, * or the handle of a semaphore (cast to a QueueSetMemberHandle_t type) contained * in the queue set that is available, or NULL if no such queue or semaphore * exists before before the specified block time expires. */ QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /* * A version of xQueueSelectFromSet() that can be used from an ISR. */ QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; /* Not public API functions. */ void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION; BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) PRIVILEGED_FUNCTION; void vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) PRIVILEGED_FUNCTION; UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* QUEUE_H */ ================================================ FILE: FreeRTOS-comparison/include/semphr.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef SEMAPHORE_H #define SEMAPHORE_H #ifndef INC_FREERTOS_H #error "include FreeRTOS.h" must appear in source files before "include semphr.h" #endif #include "queue.h" typedef QueueHandle_t SemaphoreHandle_t; #define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( uint8_t ) 1U ) #define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U ) #define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U ) /** * semphr. h * @code{c} * vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore ); * @endcode * * In many usage scenarios it is faster and more memory efficient to use a * direct to task notification in place of a binary semaphore! * https://www.FreeRTOS.org/RTOS-task-notifications.html * * This old vSemaphoreCreateBinary() macro is now deprecated in favour of the * xSemaphoreCreateBinary() function. Note that binary semaphores created using * the vSemaphoreCreateBinary() macro are created in a state such that the * first call to 'take' the semaphore would pass, whereas binary semaphores * created using xSemaphoreCreateBinary() are created in a state such that the * the semaphore must first be 'given' before it can be 'taken'. * * Macro that implements a semaphore by using the existing queue mechanism. * The queue length is 1 as this is a binary semaphore. The data size is 0 * as we don't want to actually store any data - we just want to know if the * queue is empty or full. * * This type of semaphore can be used for pure synchronisation between tasks or * between an interrupt and a task. The semaphore need not be given back once * obtained, so one task/interrupt can continuously 'give' the semaphore while * another continuously 'takes' the semaphore. For this reason this type of * semaphore does not use a priority inheritance mechanism. For an alternative * that does use priority inheritance see xSemaphoreCreateMutex(). * * @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t. * * Example usage: * @code{c} * SemaphoreHandle_t xSemaphore = NULL; * * void vATask( void * pvParameters ) * { * // Semaphore cannot be used before a call to vSemaphoreCreateBinary (). * // This is a macro so pass the variable in directly. * vSemaphoreCreateBinary( xSemaphore ); * * if( xSemaphore != NULL ) * { * // The semaphore was created successfully. * // The semaphore can now be used. * } * } * @endcode * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary * \ingroup Semaphores */ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #define vSemaphoreCreateBinary( xSemaphore ) \ { \ ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ if( ( xSemaphore ) != NULL ) \ { \ ( void ) xSemaphoreGive( ( xSemaphore ) ); \ } \ } #endif /** * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateBinary( void ); * @endcode * * Creates a new binary semaphore instance, and returns a handle by which the * new semaphore can be referenced. * * In many usage scenarios it is faster and more memory efficient to use a * direct to task notification in place of a binary semaphore! * https://www.FreeRTOS.org/RTOS-task-notifications.html * * Internally, within the FreeRTOS implementation, binary semaphores use a block * of memory, in which the semaphore structure is stored. If a binary semaphore * is created using xSemaphoreCreateBinary() then the required memory is * automatically dynamically allocated inside the xSemaphoreCreateBinary() * function. (see https://www.FreeRTOS.org/a00111.html). If a binary semaphore * is created using xSemaphoreCreateBinaryStatic() then the application writer * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a * binary semaphore to be created without using any dynamic memory allocation. * * The old vSemaphoreCreateBinary() macro is now deprecated in favour of this * xSemaphoreCreateBinary() function. Note that binary semaphores created using * the vSemaphoreCreateBinary() macro are created in a state such that the * first call to 'take' the semaphore would pass, whereas binary semaphores * created using xSemaphoreCreateBinary() are created in a state such that the * the semaphore must first be 'given' before it can be 'taken'. * * This type of semaphore can be used for pure synchronisation between tasks or * between an interrupt and a task. The semaphore need not be given back once * obtained, so one task/interrupt can continuously 'give' the semaphore while * another continuously 'takes' the semaphore. For this reason this type of * semaphore does not use a priority inheritance mechanism. For an alternative * that does use priority inheritance see xSemaphoreCreateMutex(). * * @return Handle to the created semaphore, or NULL if the memory required to * hold the semaphore's data structures could not be allocated. * * Example usage: * @code{c} * SemaphoreHandle_t xSemaphore = NULL; * * void vATask( void * pvParameters ) * { * // Semaphore cannot be used before a call to xSemaphoreCreateBinary(). * // This is a macro so pass the variable in directly. * xSemaphore = xSemaphoreCreateBinary(); * * if( xSemaphore != NULL ) * { * // The semaphore was created successfully. * // The semaphore can now be used. * } * } * @endcode * \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary * \ingroup Semaphores */ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ) #endif /** * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer ); * @endcode * * Creates a new binary semaphore instance, and returns a handle by which the * new semaphore can be referenced. * * NOTE: In many usage scenarios it is faster and more memory efficient to use a * direct to task notification in place of a binary semaphore! * https://www.FreeRTOS.org/RTOS-task-notifications.html * * Internally, within the FreeRTOS implementation, binary semaphores use a block * of memory, in which the semaphore structure is stored. If a binary semaphore * is created using xSemaphoreCreateBinary() then the required memory is * automatically dynamically allocated inside the xSemaphoreCreateBinary() * function. (see https://www.FreeRTOS.org/a00111.html). If a binary semaphore * is created using xSemaphoreCreateBinaryStatic() then the application writer * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a * binary semaphore to be created without using any dynamic memory allocation. * * This type of semaphore can be used for pure synchronisation between tasks or * between an interrupt and a task. The semaphore need not be given back once * obtained, so one task/interrupt can continuously 'give' the semaphore while * another continuously 'takes' the semaphore. For this reason this type of * semaphore does not use a priority inheritance mechanism. For an alternative * that does use priority inheritance see xSemaphoreCreateMutex(). * * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, * which will then be used to hold the semaphore's data structure, removing the * need for the memory to be allocated dynamically. * * @return If the semaphore is created then a handle to the created semaphore is * returned. If pxSemaphoreBuffer is NULL then NULL is returned. * * Example usage: * @code{c} * SemaphoreHandle_t xSemaphore = NULL; * StaticSemaphore_t xSemaphoreBuffer; * * void vATask( void * pvParameters ) * { * // Semaphore cannot be used before a call to xSemaphoreCreateBinary(). * // The semaphore's data structures will be placed in the xSemaphoreBuffer * // variable, the address of which is passed into the function. The * // function's parameter is not NULL, so the function will not attempt any * // dynamic memory allocation, and therefore the function will not return * // return NULL. * xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer ); * * // Rest of task code goes here. * } * @endcode * \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic * \ingroup Semaphores */ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) #define xSemaphoreCreateBinaryStatic( pxStaticSemaphore ) xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, ( pxStaticSemaphore ), queueQUEUE_TYPE_BINARY_SEMAPHORE ) #endif /* configSUPPORT_STATIC_ALLOCATION */ /** * semphr. h * @code{c} * xSemaphoreTake( * SemaphoreHandle_t xSemaphore, * TickType_t xBlockTime * ); * @endcode * * Macro to obtain a semaphore. The semaphore must have previously been * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or * xSemaphoreCreateCounting(). * * @param xSemaphore A handle to the semaphore being taken - obtained when * the semaphore was created. * * @param xBlockTime The time in ticks to wait for the semaphore to become * available. The macro portTICK_PERIOD_MS can be used to convert this to a * real time. A block time of zero can be used to poll the semaphore. A block * time of portMAX_DELAY can be used to block indefinitely (provided * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). * * @return pdTRUE if the semaphore was obtained. pdFALSE * if xBlockTime expired without the semaphore becoming available. * * Example usage: * @code{c} * SemaphoreHandle_t xSemaphore = NULL; * * // A task that creates a semaphore. * void vATask( void * pvParameters ) * { * // Create the semaphore to guard a shared resource. * xSemaphore = xSemaphoreCreateBinary(); * } * * // A task that uses the semaphore. * void vAnotherTask( void * pvParameters ) * { * // ... Do other things. * * if( xSemaphore != NULL ) * { * // See if we can obtain the semaphore. If the semaphore is not available * // wait 10 ticks to see if it becomes free. * if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE ) * { * // We were able to obtain the semaphore and can now access the * // shared resource. * * // ... * * // We have finished accessing the shared resource. Release the * // semaphore. * xSemaphoreGive( xSemaphore ); * } * else * { * // We could not obtain the semaphore and can therefore not access * // the shared resource safely. * } * } * } * @endcode * \defgroup xSemaphoreTake xSemaphoreTake * \ingroup Semaphores */ #define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) ) /** * semphr. h * @code{c} * xSemaphoreTakeRecursive( * SemaphoreHandle_t xMutex, * TickType_t xBlockTime * ); * @endcode * * Macro to recursively obtain, or 'take', a mutex type semaphore. * The mutex must have previously been created using a call to * xSemaphoreCreateRecursiveMutex(); * * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this * macro to be available. * * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). * * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex * doesn't become available again until the owner has called * xSemaphoreGiveRecursive() for each successful 'take' request. For example, * if a task successfully 'takes' the same mutex 5 times then the mutex will * not be available to any other task until it has also 'given' the mutex back * exactly five times. * * @param xMutex A handle to the mutex being obtained. This is the * handle returned by xSemaphoreCreateRecursiveMutex(); * * @param xBlockTime The time in ticks to wait for the semaphore to become * available. The macro portTICK_PERIOD_MS can be used to convert this to a * real time. A block time of zero can be used to poll the semaphore. If * the task already owns the semaphore then xSemaphoreTakeRecursive() will * return immediately no matter what the value of xBlockTime. * * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime * expired without the semaphore becoming available. * * Example usage: * @code{c} * SemaphoreHandle_t xMutex = NULL; * * // A task that creates a mutex. * void vATask( void * pvParameters ) * { * // Create the mutex to guard a shared resource. * xMutex = xSemaphoreCreateRecursiveMutex(); * } * * // A task that uses the mutex. * void vAnotherTask( void * pvParameters ) * { * // ... Do other things. * * if( xMutex != NULL ) * { * // See if we can obtain the mutex. If the mutex is not available * // wait 10 ticks to see if it becomes free. * if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE ) * { * // We were able to obtain the mutex and can now access the * // shared resource. * * // ... * // For some reason due to the nature of the code further calls to * // xSemaphoreTakeRecursive() are made on the same mutex. In real * // code these would not be just sequential calls as this would make * // no sense. Instead the calls are likely to be buried inside * // a more complex call structure. * xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); * xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); * * // The mutex has now been 'taken' three times, so will not be * // available to another task until it has also been given back * // three times. Again it is unlikely that real code would have * // these calls sequentially, but instead buried in a more complex * // call structure. This is just for illustrative purposes. * xSemaphoreGiveRecursive( xMutex ); * xSemaphoreGiveRecursive( xMutex ); * xSemaphoreGiveRecursive( xMutex ); * * // Now the mutex can be taken by other tasks. * } * else * { * // We could not obtain the mutex and can therefore not access * // the shared resource safely. * } * } * } * @endcode * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive * \ingroup Semaphores */ #if ( configUSE_RECURSIVE_MUTEXES == 1 ) #define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) ) #endif /** * semphr. h * @code{c} * xSemaphoreGive( SemaphoreHandle_t xSemaphore ); * @endcode * * Macro to release a semaphore. The semaphore must have previously been * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake(). * * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for * an alternative which can be used from an ISR. * * This macro must also not be used on semaphores created using * xSemaphoreCreateRecursiveMutex(). * * @param xSemaphore A handle to the semaphore being released. This is the * handle returned when the semaphore was created. * * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred. * Semaphores are implemented using queues. An error can occur if there is * no space on the queue to post a message - indicating that the * semaphore was not first obtained correctly. * * Example usage: * @code{c} * SemaphoreHandle_t xSemaphore = NULL; * * void vATask( void * pvParameters ) * { * // Create the semaphore to guard a shared resource. * xSemaphore = vSemaphoreCreateBinary(); * * if( xSemaphore != NULL ) * { * if( xSemaphoreGive( xSemaphore ) != pdTRUE ) * { * // We would expect this call to fail because we cannot give * // a semaphore without first "taking" it! * } * * // Obtain the semaphore - don't block if the semaphore is not * // immediately available. * if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) ) * { * // We now have the semaphore and can access the shared resource. * * // ... * * // We have finished accessing the shared resource so can free the * // semaphore. * if( xSemaphoreGive( xSemaphore ) != pdTRUE ) * { * // We would not expect this call to fail because we must have * // obtained the semaphore to get here. * } * } * } * } * @endcode * \defgroup xSemaphoreGive xSemaphoreGive * \ingroup Semaphores */ #define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) /** * semphr. h * @code{c} * xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex ); * @endcode * * Macro to recursively release, or 'give', a mutex type semaphore. * The mutex must have previously been created using a call to * xSemaphoreCreateRecursiveMutex(); * * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this * macro to be available. * * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). * * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex * doesn't become available again until the owner has called * xSemaphoreGiveRecursive() for each successful 'take' request. For example, * if a task successfully 'takes' the same mutex 5 times then the mutex will * not be available to any other task until it has also 'given' the mutex back * exactly five times. * * @param xMutex A handle to the mutex being released, or 'given'. This is the * handle returned by xSemaphoreCreateMutex(); * * @return pdTRUE if the semaphore was given. * * Example usage: * @code{c} * SemaphoreHandle_t xMutex = NULL; * * // A task that creates a mutex. * void vATask( void * pvParameters ) * { * // Create the mutex to guard a shared resource. * xMutex = xSemaphoreCreateRecursiveMutex(); * } * * // A task that uses the mutex. * void vAnotherTask( void * pvParameters ) * { * // ... Do other things. * * if( xMutex != NULL ) * { * // See if we can obtain the mutex. If the mutex is not available * // wait 10 ticks to see if it becomes free. * if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE ) * { * // We were able to obtain the mutex and can now access the * // shared resource. * * // ... * // For some reason due to the nature of the code further calls to * // xSemaphoreTakeRecursive() are made on the same mutex. In real * // code these would not be just sequential calls as this would make * // no sense. Instead the calls are likely to be buried inside * // a more complex call structure. * xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); * xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); * * // The mutex has now been 'taken' three times, so will not be * // available to another task until it has also been given back * // three times. Again it is unlikely that real code would have * // these calls sequentially, it would be more likely that the calls * // to xSemaphoreGiveRecursive() would be called as a call stack * // unwound. This is just for demonstrative purposes. * xSemaphoreGiveRecursive( xMutex ); * xSemaphoreGiveRecursive( xMutex ); * xSemaphoreGiveRecursive( xMutex ); * * // Now the mutex can be taken by other tasks. * } * else * { * // We could not obtain the mutex and can therefore not access * // the shared resource safely. * } * } * } * @endcode * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive * \ingroup Semaphores */ #if ( configUSE_RECURSIVE_MUTEXES == 1 ) #define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) ) #endif /** * semphr. h * @code{c} * xSemaphoreGiveFromISR( * SemaphoreHandle_t xSemaphore, * BaseType_t *pxHigherPriorityTaskWoken * ); * @endcode * * Macro to release a semaphore. The semaphore must have previously been * created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting(). * * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) * must not be used with this macro. * * This macro can be used from an ISR. * * @param xSemaphore A handle to the semaphore being released. This is the * handle returned when the semaphore was created. * * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task * to unblock, and the unblocked task has a priority higher than the currently * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then * a context switch should be requested before the interrupt is exited. * * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL. * * Example usage: * @code{c} \#define LONG_TIME 0xffff \#define TICKS_TO_WAIT 10 * SemaphoreHandle_t xSemaphore = NULL; * * // Repetitive task. * void vATask( void * pvParameters ) * { * for( ;; ) * { * // We want this task to run every 10 ticks of a timer. The semaphore * // was created before this task was started. * * // Block waiting for the semaphore to become available. * if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE ) * { * // It is time to execute. * * // ... * * // We have finished our task. Return to the top of the loop where * // we will block on the semaphore until it is time to execute * // again. Note when using the semaphore for synchronisation with an * // ISR in this manner there is no need to 'give' the semaphore back. * } * } * } * * // Timer ISR * void vTimerISR( void * pvParameters ) * { * static uint8_t ucLocalTickCount = 0; * static BaseType_t xHigherPriorityTaskWoken; * * // A timer tick has occurred. * * // ... Do other time functions. * * // Is it time for vATask () to run? * xHigherPriorityTaskWoken = pdFALSE; * ucLocalTickCount++; * if( ucLocalTickCount >= TICKS_TO_WAIT ) * { * // Unblock the task by releasing the semaphore. * xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken ); * * // Reset the count so we release the semaphore again in 10 ticks time. * ucLocalTickCount = 0; * } * * if( xHigherPriorityTaskWoken != pdFALSE ) * { * // We can force a context switch here. Context switching from an * // ISR uses port specific syntax. Check the demo task for your port * // to find the syntax required. * } * } * @endcode * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR * \ingroup Semaphores */ #define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) ) /** * semphr. h * @code{c} * xSemaphoreTakeFromISR( * SemaphoreHandle_t xSemaphore, * BaseType_t *pxHigherPriorityTaskWoken * ); * @endcode * * Macro to take a semaphore from an ISR. The semaphore must have * previously been created with a call to xSemaphoreCreateBinary() or * xSemaphoreCreateCounting(). * * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) * must not be used with this macro. * * This macro can be used from an ISR, however taking a semaphore from an ISR * is not a common operation. It is likely to only be useful when taking a * counting semaphore when an interrupt is obtaining an object from a resource * pool (when the semaphore count indicates the number of resources available). * * @param xSemaphore A handle to the semaphore being taken. This is the * handle returned when the semaphore was created. * * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task * to unblock, and the unblocked task has a priority higher than the currently * running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then * a context switch should be requested before the interrupt is exited. * * @return pdTRUE if the semaphore was successfully taken, otherwise * pdFALSE */ #define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) ) /** * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateMutex( void ); * @endcode * * Creates a new mutex type semaphore instance, and returns a handle by which * the new mutex can be referenced. * * Internally, within the FreeRTOS implementation, mutex semaphores use a block * of memory, in which the mutex structure is stored. If a mutex is created * using xSemaphoreCreateMutex() then the required memory is automatically * dynamically allocated inside the xSemaphoreCreateMutex() function. (see * https://www.FreeRTOS.org/a00111.html). If a mutex is created using * xSemaphoreCreateMutexStatic() then the application writer must provided the * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created * without using any dynamic memory allocation. * * Mutexes created using this function can be accessed using the xSemaphoreTake() * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and * xSemaphoreGiveRecursive() macros must not be used. * * This type of semaphore uses a priority inheritance mechanism so a task * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the * semaphore it is no longer required. * * Mutex type semaphores cannot be used from within interrupt service routines. * * See xSemaphoreCreateBinary() for an alternative implementation that can be * used for pure synchronisation (where one task or interrupt always 'gives' the * semaphore and another always 'takes' the semaphore) and from within interrupt * service routines. * * @return If the mutex was successfully created then a handle to the created * semaphore is returned. If there was not enough heap to allocate the mutex * data structures then NULL is returned. * * Example usage: * @code{c} * SemaphoreHandle_t xSemaphore; * * void vATask( void * pvParameters ) * { * // Semaphore cannot be used before a call to xSemaphoreCreateMutex(). * // This is a macro so pass the variable in directly. * xSemaphore = xSemaphoreCreateMutex(); * * if( xSemaphore != NULL ) * { * // The semaphore was created successfully. * // The semaphore can now be used. * } * } * @endcode * \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex * \ingroup Semaphores */ #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_MUTEXES == 1 ) ) #define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX ) #endif /** * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer ); * @endcode * * Creates a new mutex type semaphore instance, and returns a handle by which * the new mutex can be referenced. * * Internally, within the FreeRTOS implementation, mutex semaphores use a block * of memory, in which the mutex structure is stored. If a mutex is created * using xSemaphoreCreateMutex() then the required memory is automatically * dynamically allocated inside the xSemaphoreCreateMutex() function. (see * https://www.FreeRTOS.org/a00111.html). If a mutex is created using * xSemaphoreCreateMutexStatic() then the application writer must provided the * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created * without using any dynamic memory allocation. * * Mutexes created using this function can be accessed using the xSemaphoreTake() * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and * xSemaphoreGiveRecursive() macros must not be used. * * This type of semaphore uses a priority inheritance mechanism so a task * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the * semaphore it is no longer required. * * Mutex type semaphores cannot be used from within interrupt service routines. * * See xSemaphoreCreateBinary() for an alternative implementation that can be * used for pure synchronisation (where one task or interrupt always 'gives' the * semaphore and another always 'takes' the semaphore) and from within interrupt * service routines. * * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, * which will be used to hold the mutex's data structure, removing the need for * the memory to be allocated dynamically. * * @return If the mutex was successfully created then a handle to the created * mutex is returned. If pxMutexBuffer was NULL then NULL is returned. * * Example usage: * @code{c} * SemaphoreHandle_t xSemaphore; * StaticSemaphore_t xMutexBuffer; * * void vATask( void * pvParameters ) * { * // A mutex cannot be used before it has been created. xMutexBuffer is * // into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is * // attempted. * xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer ); * * // As no dynamic memory allocation was performed, xSemaphore cannot be NULL, * // so there is no need to check it. * } * @endcode * \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic * \ingroup Semaphores */ #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_MUTEXES == 1 ) ) #define xSemaphoreCreateMutexStatic( pxMutexBuffer ) xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) ) #endif /** * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void ); * @endcode * * Creates a new recursive mutex type semaphore instance, and returns a handle * by which the new recursive mutex can be referenced. * * Internally, within the FreeRTOS implementation, recursive mutexes use a block * of memory, in which the mutex structure is stored. If a recursive mutex is * created using xSemaphoreCreateRecursiveMutex() then the required memory is * automatically dynamically allocated inside the * xSemaphoreCreateRecursiveMutex() function. (see * https://www.FreeRTOS.org/a00111.html). If a recursive mutex is created using * xSemaphoreCreateRecursiveMutexStatic() then the application writer must * provide the memory that will get used by the mutex. * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to * be created without using any dynamic memory allocation. * * Mutexes created using this macro can be accessed using the * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The * xSemaphoreTake() and xSemaphoreGive() macros must not be used. * * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex * doesn't become available again until the owner has called * xSemaphoreGiveRecursive() for each successful 'take' request. For example, * if a task successfully 'takes' the same mutex 5 times then the mutex will * not be available to any other task until it has also 'given' the mutex back * exactly five times. * * This type of semaphore uses a priority inheritance mechanism so a task * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the * semaphore it is no longer required. * * Mutex type semaphores cannot be used from within interrupt service routines. * * See xSemaphoreCreateBinary() for an alternative implementation that can be * used for pure synchronisation (where one task or interrupt always 'gives' the * semaphore and another always 'takes' the semaphore) and from within interrupt * service routines. * * @return xSemaphore Handle to the created mutex semaphore. Should be of type * SemaphoreHandle_t. * * Example usage: * @code{c} * SemaphoreHandle_t xSemaphore; * * void vATask( void * pvParameters ) * { * // Semaphore cannot be used before a call to xSemaphoreCreateMutex(). * // This is a macro so pass the variable in directly. * xSemaphore = xSemaphoreCreateRecursiveMutex(); * * if( xSemaphore != NULL ) * { * // The semaphore was created successfully. * // The semaphore can now be used. * } * } * @endcode * \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex * \ingroup Semaphores */ #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX ) #endif /** * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic( StaticSemaphore_t *pxMutexBuffer ); * @endcode * * Creates a new recursive mutex type semaphore instance, and returns a handle * by which the new recursive mutex can be referenced. * * Internally, within the FreeRTOS implementation, recursive mutexes use a block * of memory, in which the mutex structure is stored. If a recursive mutex is * created using xSemaphoreCreateRecursiveMutex() then the required memory is * automatically dynamically allocated inside the * xSemaphoreCreateRecursiveMutex() function. (see * https://www.FreeRTOS.org/a00111.html). If a recursive mutex is created using * xSemaphoreCreateRecursiveMutexStatic() then the application writer must * provide the memory that will get used by the mutex. * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to * be created without using any dynamic memory allocation. * * Mutexes created using this macro can be accessed using the * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The * xSemaphoreTake() and xSemaphoreGive() macros must not be used. * * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex * doesn't become available again until the owner has called * xSemaphoreGiveRecursive() for each successful 'take' request. For example, * if a task successfully 'takes' the same mutex 5 times then the mutex will * not be available to any other task until it has also 'given' the mutex back * exactly five times. * * This type of semaphore uses a priority inheritance mechanism so a task * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the * semaphore it is no longer required. * * Mutex type semaphores cannot be used from within interrupt service routines. * * See xSemaphoreCreateBinary() for an alternative implementation that can be * used for pure synchronisation (where one task or interrupt always 'gives' the * semaphore and another always 'takes' the semaphore) and from within interrupt * service routines. * * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, * which will then be used to hold the recursive mutex's data structure, * removing the need for the memory to be allocated dynamically. * * @return If the recursive mutex was successfully created then a handle to the * created recursive mutex is returned. If pxMutexBuffer was NULL then NULL is * returned. * * Example usage: * @code{c} * SemaphoreHandle_t xSemaphore; * StaticSemaphore_t xMutexBuffer; * * void vATask( void * pvParameters ) * { * // A recursive semaphore cannot be used before it is created. Here a * // recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic(). * // The address of xMutexBuffer is passed into the function, and will hold * // the mutexes data structures - so no dynamic memory allocation will be * // attempted. * xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer ); * * // As no dynamic memory allocation was performed, xSemaphore cannot be NULL, * // so there is no need to check it. * } * @endcode * \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic * \ingroup Semaphores */ #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) #define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore ) xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, ( pxStaticSemaphore ) ) #endif /* configSUPPORT_STATIC_ALLOCATION */ /** * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount ); * @endcode * * Creates a new counting semaphore instance, and returns a handle by which the * new counting semaphore can be referenced. * * In many usage scenarios it is faster and more memory efficient to use a * direct to task notification in place of a counting semaphore! * https://www.FreeRTOS.org/RTOS-task-notifications.html * * Internally, within the FreeRTOS implementation, counting semaphores use a * block of memory, in which the counting semaphore structure is stored. If a * counting semaphore is created using xSemaphoreCreateCounting() then the * required memory is automatically dynamically allocated inside the * xSemaphoreCreateCounting() function. (see * https://www.FreeRTOS.org/a00111.html). If a counting semaphore is created * using xSemaphoreCreateCountingStatic() then the application writer can * instead optionally provide the memory that will get used by the counting * semaphore. xSemaphoreCreateCountingStatic() therefore allows a counting * semaphore to be created without using any dynamic memory allocation. * * Counting semaphores are typically used for two things: * * 1) Counting events. * * In this usage scenario an event handler will 'give' a semaphore each time * an event occurs (incrementing the semaphore count value), and a handler * task will 'take' a semaphore each time it processes an event * (decrementing the semaphore count value). The count value is therefore * the difference between the number of events that have occurred and the * number that have been processed. In this case it is desirable for the * initial count value to be zero. * * 2) Resource management. * * In this usage scenario the count value indicates the number of resources * available. To obtain control of a resource a task must first obtain a * semaphore - decrementing the semaphore count value. When the count value * reaches zero there are no free resources. When a task finishes with the * resource it 'gives' the semaphore back - incrementing the semaphore count * value. In this case it is desirable for the initial count value to be * equal to the maximum count value, indicating that all resources are free. * * @param uxMaxCount The maximum count value that can be reached. When the * semaphore reaches this value it can no longer be 'given'. * * @param uxInitialCount The count value assigned to the semaphore when it is * created. * * @return Handle to the created semaphore. Null if the semaphore could not be * created. * * Example usage: * @code{c} * SemaphoreHandle_t xSemaphore; * * void vATask( void * pvParameters ) * { * SemaphoreHandle_t xSemaphore = NULL; * * // Semaphore cannot be used before a call to xSemaphoreCreateCounting(). * // The max value to which the semaphore can count should be 10, and the * // initial value assigned to the count should be 0. * xSemaphore = xSemaphoreCreateCounting( 10, 0 ); * * if( xSemaphore != NULL ) * { * // The semaphore was created successfully. * // The semaphore can now be used. * } * } * @endcode * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting * \ingroup Semaphores */ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) ) #endif /** * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer ); * @endcode * * Creates a new counting semaphore instance, and returns a handle by which the * new counting semaphore can be referenced. * * In many usage scenarios it is faster and more memory efficient to use a * direct to task notification in place of a counting semaphore! * https://www.FreeRTOS.org/RTOS-task-notifications.html * * Internally, within the FreeRTOS implementation, counting semaphores use a * block of memory, in which the counting semaphore structure is stored. If a * counting semaphore is created using xSemaphoreCreateCounting() then the * required memory is automatically dynamically allocated inside the * xSemaphoreCreateCounting() function. (see * https://www.FreeRTOS.org/a00111.html). If a counting semaphore is created * using xSemaphoreCreateCountingStatic() then the application writer must * provide the memory. xSemaphoreCreateCountingStatic() therefore allows a * counting semaphore to be created without using any dynamic memory allocation. * * Counting semaphores are typically used for two things: * * 1) Counting events. * * In this usage scenario an event handler will 'give' a semaphore each time * an event occurs (incrementing the semaphore count value), and a handler * task will 'take' a semaphore each time it processes an event * (decrementing the semaphore count value). The count value is therefore * the difference between the number of events that have occurred and the * number that have been processed. In this case it is desirable for the * initial count value to be zero. * * 2) Resource management. * * In this usage scenario the count value indicates the number of resources * available. To obtain control of a resource a task must first obtain a * semaphore - decrementing the semaphore count value. When the count value * reaches zero there are no free resources. When a task finishes with the * resource it 'gives' the semaphore back - incrementing the semaphore count * value. In this case it is desirable for the initial count value to be * equal to the maximum count value, indicating that all resources are free. * * @param uxMaxCount The maximum count value that can be reached. When the * semaphore reaches this value it can no longer be 'given'. * * @param uxInitialCount The count value assigned to the semaphore when it is * created. * * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, * which will then be used to hold the semaphore's data structure, removing the * need for the memory to be allocated dynamically. * * @return If the counting semaphore was successfully created then a handle to * the created counting semaphore is returned. If pxSemaphoreBuffer was NULL * then NULL is returned. * * Example usage: * @code{c} * SemaphoreHandle_t xSemaphore; * StaticSemaphore_t xSemaphoreBuffer; * * void vATask( void * pvParameters ) * { * SemaphoreHandle_t xSemaphore = NULL; * * // Counting semaphore cannot be used before they have been created. Create * // a counting semaphore using xSemaphoreCreateCountingStatic(). The max * // value to which the semaphore can count is 10, and the initial value * // assigned to the count will be 0. The address of xSemaphoreBuffer is * // passed in and will be used to hold the semaphore structure, so no dynamic * // memory allocation will be used. * xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer ); * * // No memory allocation was attempted so xSemaphore cannot be NULL, so there * // is no need to check its value. * } * @endcode * \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic * \ingroup Semaphores */ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) #define xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer ) xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) ) #endif /* configSUPPORT_STATIC_ALLOCATION */ /** * semphr. h * @code{c} * void vSemaphoreDelete( SemaphoreHandle_t xSemaphore ); * @endcode * * Delete a semaphore. This function must be used with care. For example, * do not delete a mutex type semaphore if the mutex is held by a task. * * @param xSemaphore A handle to the semaphore to be deleted. * * \defgroup vSemaphoreDelete vSemaphoreDelete * \ingroup Semaphores */ #define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) ) /** * semphr.h * @code{c} * TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex ); * @endcode * * If xMutex is indeed a mutex type semaphore, return the current mutex holder. * If xMutex is not a mutex type semaphore, or the mutex is available (not held * by a task), return NULL. * * Note: This is a good way of determining if the calling task is the mutex * holder, but not a good way of determining the identity of the mutex holder as * the holder may change between the function exiting and the returned value * being tested. */ #if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) #define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) #endif /** * semphr.h * @code{c} * TaskHandle_t xSemaphoreGetMutexHolderFromISR( SemaphoreHandle_t xMutex ); * @endcode * * If xMutex is indeed a mutex type semaphore, return the current mutex holder. * If xMutex is not a mutex type semaphore, or the mutex is available (not held * by a task), return NULL. * */ #if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) #define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) ) #endif /** * semphr.h * @code{c} * UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore ); * @endcode * * If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns * its current count value. If the semaphore is a binary semaphore then * uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the * semaphore is not available. * */ #define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) ) /** * semphr.h * @code{c} * UBaseType_t uxSemaphoreGetCountFromISR( SemaphoreHandle_t xSemaphore ); * @endcode * * If the semaphore is a counting semaphore then uxSemaphoreGetCountFromISR() returns * its current count value. If the semaphore is a binary semaphore then * uxSemaphoreGetCountFromISR() returns 1 if the semaphore is available, and 0 if the * semaphore is not available. * */ #define uxSemaphoreGetCountFromISR( xSemaphore ) uxQueueMessagesWaitingFromISR( ( QueueHandle_t ) ( xSemaphore ) ) #endif /* SEMAPHORE_H */ ================================================ FILE: FreeRTOS-comparison/include/stack_macros.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef STACK_MACROS_H #define STACK_MACROS_H /* * Call the stack overflow hook function if the stack of the task being swapped * out is currently overflowed, or looks like it might have overflowed in the * past. * * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check * the current stack state only - comparing the current top of stack value to * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 * will also cause the last few stack bytes to be checked to ensure the value * to which the bytes were set when the task was created have not been * overwritten. Note this second test does not guarantee that an overflowed * stack will always be recognised. */ /*-----------------------------------------------------------*/ /* * portSTACK_LIMIT_PADDING is a number of extra words to consider to be in * use on the stack. */ #ifndef portSTACK_LIMIT_PADDING #define portSTACK_LIMIT_PADDING 0 #endif #if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) /* Only the current stack state is to be checked. */ #define taskCHECK_FOR_STACK_OVERFLOW() \ { \ /* Is the currently saved stack pointer within the stack limit? */ \ if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \ { \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ } \ } #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ /*-----------------------------------------------------------*/ #if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) /* Only the current stack state is to be checked. */ #define taskCHECK_FOR_STACK_OVERFLOW() \ { \ \ /* Is the currently saved stack pointer within the stack limit? */ \ if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \ { \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ } \ } #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ /*-----------------------------------------------------------*/ #if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) #define taskCHECK_FOR_STACK_OVERFLOW() \ { \ const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ \ if( ( pulStack[ 0 ] != ulCheckValue ) || \ ( pulStack[ 1 ] != ulCheckValue ) || \ ( pulStack[ 2 ] != ulCheckValue ) || \ ( pulStack[ 3 ] != ulCheckValue ) ) \ { \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ } \ } #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ /*-----------------------------------------------------------*/ #if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) #define taskCHECK_FOR_STACK_OVERFLOW() \ { \ int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ \ \ pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ \ /* Has the extremity of the task stack ever been written over? */ \ if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ { \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ } \ } #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ /*-----------------------------------------------------------*/ /* Remove stack overflow macro if not being used. */ #ifndef taskCHECK_FOR_STACK_OVERFLOW #define taskCHECK_FOR_STACK_OVERFLOW() #endif #endif /* STACK_MACROS_H */ ================================================ FILE: FreeRTOS-comparison/include/stdint.readme ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef FREERTOS_STDINT #define FREERTOS_STDINT /******************************************************************************* * THIS IS NOT A FULL stdint.h IMPLEMENTATION - It only contains the definitions * necessary to build the FreeRTOS code. It is provided to allow FreeRTOS to be * built using compilers that do not provide their own stdint.h definition. * * To use this file: * * 1) Copy this file into the directory that contains your FreeRTOSConfig.h * header file, as that directory will already be in the compiler's include * path. * * 2) Rename the copied file stdint.h. * */ typedef signed char int8_t; typedef unsigned char uint8_t; typedef short int16_t; typedef unsigned short uint16_t; typedef long int32_t; typedef unsigned long uint32_t; #ifndef SIZE_MAX #define SIZE_MAX ( ( size_t ) -1 ) #endif #endif /* FREERTOS_STDINT */ ================================================ FILE: FreeRTOS-comparison/include/stream_buffer.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* * Stream buffers are used to send a continuous stream of data from one task or * interrupt to another. Their implementation is light weight, making them * particularly suited for interrupt to task and core to core communication * scenarios. * * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer * implementation (so also the message buffer implementation, as message buffers * are built on top of stream buffers) assumes there is only one task or * interrupt that will write to the buffer (the writer), and only one task or * interrupt that will read from the buffer (the reader). It is safe for the * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers * then the application writer must place each call to a writing API function * (such as xStreamBufferSend()) inside a critical section and set the send * block time to 0. Likewise, if there are to be multiple different readers * then the application writer must place each call to a reading API function * (such as xStreamBufferReceive()) inside a critical section section and set the * receive block time to 0. * */ #ifndef STREAM_BUFFER_H #define STREAM_BUFFER_H #ifndef INC_FREERTOS_H #error "include FreeRTOS.h must appear in source files before include stream_buffer.h" #endif /* *INDENT-OFF* */ #if defined( __cplusplus ) extern "C" { #endif /* *INDENT-ON* */ /** * Type by which stream buffers are referenced. For example, a call to * xStreamBufferCreate() returns an StreamBufferHandle_t variable that can * then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(), * etc. */ struct StreamBufferDef_t; typedef struct StreamBufferDef_t * StreamBufferHandle_t; /** * Type used as a stream buffer's optional callback. */ typedef void (* StreamBufferCallbackFunction_t)( StreamBufferHandle_t xStreamBuffer, BaseType_t xIsInsideISR, BaseType_t * const pxHigherPriorityTaskWoken ); /** * stream_buffer.h * * @code{c} * StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes ); * @endcode * * Creates a new stream buffer using dynamically allocated memory. See * xStreamBufferCreateStatic() for a version that uses statically allocated * memory (memory that is allocated at compile time). * * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in * FreeRTOSConfig.h for xStreamBufferCreate() to be available. * * @param xBufferSizeBytes The total number of bytes the stream buffer will be * able to hold at any one time. * * @param xTriggerLevelBytes The number of bytes that must be in the stream * buffer before a task that is blocked on the stream buffer to wait for data is * moved out of the blocked state. For example, if a task is blocked on a read * of an empty stream buffer that has a trigger level of 1 then the task will be * unblocked when a single byte is written to the buffer or the task's block * time expires. As another example, if a task is blocked on a read of an empty * stream buffer that has a trigger level of 10 then the task will not be * unblocked until the stream buffer contains at least 10 bytes or the task's * block time expires. If a reading task's block time expires before the * trigger level is reached then the task will still receive however many bytes * are actually available. Setting a trigger level of 0 will result in a * trigger level of 1 being used. It is not valid to specify a trigger level * that is greater than the buffer size. * * @param pxSendCompletedCallback Callback invoked when number of bytes at least equal to * trigger level is sent to the stream buffer. If the parameter is NULL, it will use the default * implementation provided by sbSEND_COMPLETED macro. To enable the callback, * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h. * * @param pxReceiveCompletedCallback Callback invoked when more than zero bytes are read from a * stream buffer. If the parameter is NULL, it will use the default * implementation provided by sbRECEIVE_COMPLETED macro. To enable the callback, * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h. * * @return If NULL is returned, then the stream buffer cannot be created * because there is insufficient heap memory available for FreeRTOS to allocate * the stream buffer data structures and storage area. A non-NULL value being * returned indicates that the stream buffer has been created successfully - * the returned value should be stored as the handle to the created stream * buffer. * * Example use: * @code{c} * * void vAFunction( void ) * { * StreamBufferHandle_t xStreamBuffer; * const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10; * * // Create a stream buffer that can hold 100 bytes. The memory used to hold * // both the stream buffer structure and the data in the stream buffer is * // allocated dynamically. * xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel ); * * if( xStreamBuffer == NULL ) * { * // There was not enough heap memory space available to create the * // stream buffer. * } * else * { * // The stream buffer was created successfully and can now be used. * } * } * @endcode * \defgroup xStreamBufferCreate xStreamBufferCreate * \ingroup StreamBufferManagement */ #define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) \ xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, NULL, NULL ) #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define xStreamBufferCreateWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) #endif /** * stream_buffer.h * * @code{c} * StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes, * size_t xTriggerLevelBytes, * uint8_t *pucStreamBufferStorageArea, * StaticStreamBuffer_t *pxStaticStreamBuffer ); * @endcode * Creates a new stream buffer using statically allocated memory. See * xStreamBufferCreate() for a version that uses dynamically allocated memory. * * configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h for * xStreamBufferCreateStatic() to be available. * * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the * pucStreamBufferStorageArea parameter. * * @param xTriggerLevelBytes The number of bytes that must be in the stream * buffer before a task that is blocked on the stream buffer to wait for data is * moved out of the blocked state. For example, if a task is blocked on a read * of an empty stream buffer that has a trigger level of 1 then the task will be * unblocked when a single byte is written to the buffer or the task's block * time expires. As another example, if a task is blocked on a read of an empty * stream buffer that has a trigger level of 10 then the task will not be * unblocked until the stream buffer contains at least 10 bytes or the task's * block time expires. If a reading task's block time expires before the * trigger level is reached then the task will still receive however many bytes * are actually available. Setting a trigger level of 0 will result in a * trigger level of 1 being used. It is not valid to specify a trigger level * that is greater than the buffer size. * * @param pucStreamBufferStorageArea Must point to a uint8_t array that is at * least xBufferSizeBytes big. This is the array to which streams are * copied when they are written to the stream buffer. * * @param pxStaticStreamBuffer Must point to a variable of type * StaticStreamBuffer_t, which will be used to hold the stream buffer's data * structure. * * @param pxSendCompletedCallback Callback invoked when number of bytes at least equal to * trigger level is sent to the stream buffer. If the parameter is NULL, it will use the default * implementation provided by sbSEND_COMPLETED macro. To enable the callback, * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h. * * @param pxReceiveCompletedCallback Callback invoked when more than zero bytes are read from a * stream buffer. If the parameter is NULL, it will use the default * implementation provided by sbRECEIVE_COMPLETED macro. To enable the callback, * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h. * * @return If the stream buffer is created successfully then a handle to the * created stream buffer is returned. If either pucStreamBufferStorageArea or * pxStaticstreamBuffer are NULL then NULL is returned. * * Example use: * @code{c} * * // Used to dimension the array used to hold the streams. The available space * // will actually be one less than this, so 999. #define STORAGE_SIZE_BYTES 1000 * * // Defines the memory that will actually hold the streams within the stream * // buffer. * static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ]; * * // The variable used to hold the stream buffer structure. * StaticStreamBuffer_t xStreamBufferStruct; * * void MyFunction( void ) * { * StreamBufferHandle_t xStreamBuffer; * const size_t xTriggerLevel = 1; * * xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucStorageBuffer ), * xTriggerLevel, * ucStorageBuffer, * &xStreamBufferStruct ); * * // As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer * // parameters were NULL, xStreamBuffer will not be NULL, and can be used to * // reference the created stream buffer in other stream buffer API calls. * * // Other code that uses the stream buffer can go here. * } * * @endcode * \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic * \ingroup StreamBufferManagement */ #define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) \ xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), NULL, NULL ) #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define xStreamBufferCreateStaticWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) #endif /** * stream_buffer.h * * @code{c} * size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, * const void *pvTxData, * size_t xDataLengthBytes, * TickType_t xTicksToWait ); * @endcode * * Sends bytes to a stream buffer. The bytes are copied into the stream buffer. * * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer * implementation (so also the message buffer implementation, as message buffers * are built on top of stream buffers) assumes there is only one task or * interrupt that will write to the buffer (the writer), and only one task or * interrupt that will read from the buffer (the reader). It is safe for the * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers * then the application writer must place each call to a writing API function * (such as xStreamBufferSend()) inside a critical section and set the send * block time to 0. Likewise, if there are to be multiple different readers * then the application writer must place each call to a reading API function * (such as xStreamBufferReceive()) inside a critical section and set the receive * block time to 0. * * Use xStreamBufferSend() to write to a stream buffer from a task. Use * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt * service routine (ISR). * * @param xStreamBuffer The handle of the stream buffer to which a stream is * being sent. * * @param pvTxData A pointer to the buffer that holds the bytes to be copied * into the stream buffer. * * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData * into the stream buffer. * * @param xTicksToWait The maximum amount of time the task should remain in the * Blocked state to wait for enough space to become available in the stream * buffer, should the stream buffer contain too little space to hold the * another xDataLengthBytes bytes. The block time is specified in tick periods, * so the absolute time it represents is dependent on the tick frequency. The * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds * into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will * cause the task to wait indefinitely (without timing out), provided * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. If a task times out * before it can write all xDataLengthBytes into the buffer it will still write * as many bytes as possible. A task does not use any CPU time when it is in * the blocked state. * * @return The number of bytes written to the stream buffer. If a task times * out before it can write all xDataLengthBytes into the buffer it will still * write as many bytes as possible. * * Example use: * @code{c} * void vAFunction( StreamBufferHandle_t xStreamBuffer ) * { * size_t xBytesSent; * uint8_t ucArrayToSend[] = { 0, 1, 2, 3 }; * char *pcStringToSend = "String to send"; * const TickType_t x100ms = pdMS_TO_TICKS( 100 ); * * // Send an array to the stream buffer, blocking for a maximum of 100ms to * // wait for enough space to be available in the stream buffer. * xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms ); * * if( xBytesSent != sizeof( ucArrayToSend ) ) * { * // The call to xStreamBufferSend() times out before there was enough * // space in the buffer for the data to be written, but it did * // successfully write xBytesSent bytes. * } * * // Send the string to the stream buffer. Return immediately if there is not * // enough space in the buffer. * xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 ); * * if( xBytesSent != strlen( pcStringToSend ) ) * { * // The entire string could not be added to the stream buffer because * // there was not enough free space in the buffer, but xBytesSent bytes * // were sent. Could try again to send the remaining bytes. * } * } * @endcode * \defgroup xStreamBufferSend xStreamBufferSend * \ingroup StreamBufferManagement */ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void * pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** * stream_buffer.h * * @code{c} * size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, * const void *pvTxData, * size_t xDataLengthBytes, * BaseType_t *pxHigherPriorityTaskWoken ); * @endcode * * Interrupt safe version of the API function that sends a stream of bytes to * the stream buffer. * * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer * implementation (so also the message buffer implementation, as message buffers * are built on top of stream buffers) assumes there is only one task or * interrupt that will write to the buffer (the writer), and only one task or * interrupt that will read from the buffer (the reader). It is safe for the * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers * then the application writer must place each call to a writing API function * (such as xStreamBufferSend()) inside a critical section and set the send * block time to 0. Likewise, if there are to be multiple different readers * then the application writer must place each call to a reading API function * (such as xStreamBufferReceive()) inside a critical section and set the receive * block time to 0. * * Use xStreamBufferSend() to write to a stream buffer from a task. Use * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt * service routine (ISR). * * @param xStreamBuffer The handle of the stream buffer to which a stream is * being sent. * * @param pvTxData A pointer to the data that is to be copied into the stream * buffer. * * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData * into the stream buffer. * * @param pxHigherPriorityTaskWoken It is possible that a stream buffer will * have a task blocked on it waiting for data. Calling * xStreamBufferSendFromISR() can make data available, and so cause a task that * was waiting for data to leave the Blocked state. If calling * xStreamBufferSendFromISR() causes a task to leave the Blocked state, and the * unblocked task has a priority higher than the currently executing task (the * task that was interrupted), then, internally, xStreamBufferSendFromISR() * will set *pxHigherPriorityTaskWoken to pdTRUE. If * xStreamBufferSendFromISR() sets this value to pdTRUE, then normally a * context switch should be performed before the interrupt is exited. This will * ensure that the interrupt returns directly to the highest priority Ready * state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it * is passed into the function. See the example code below for an example. * * @return The number of bytes actually written to the stream buffer, which will * be less than xDataLengthBytes if the stream buffer didn't have enough free * space for all the bytes to be written. * * Example use: * @code{c} * // A stream buffer that has already been created. * StreamBufferHandle_t xStreamBuffer; * * void vAnInterruptServiceRoutine( void ) * { * size_t xBytesSent; * char *pcStringToSend = "String to send"; * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. * * // Attempt to send the string to the stream buffer. * xBytesSent = xStreamBufferSendFromISR( xStreamBuffer, * ( void * ) pcStringToSend, * strlen( pcStringToSend ), * &xHigherPriorityTaskWoken ); * * if( xBytesSent != strlen( pcStringToSend ) ) * { * // There was not enough free space in the stream buffer for the entire * // string to be written, ut xBytesSent bytes were written. * } * * // If xHigherPriorityTaskWoken was set to pdTRUE inside * // xStreamBufferSendFromISR() then a task that has a priority above the * // priority of the currently executing task was unblocked and a context * // switch should be performed to ensure the ISR returns to the unblocked * // task. In most FreeRTOS ports this is done by simply passing * // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the * // variables value, and perform the context switch if necessary. Check the * // documentation for the port in use for port specific instructions. * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * } * @endcode * \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR * \ingroup StreamBufferManagement */ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, const void * pvTxData, size_t xDataLengthBytes, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; /** * stream_buffer.h * * @code{c} * size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, * void *pvRxData, * size_t xBufferLengthBytes, * TickType_t xTicksToWait ); * @endcode * * Receives bytes from a stream buffer. * * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer * implementation (so also the message buffer implementation, as message buffers * are built on top of stream buffers) assumes there is only one task or * interrupt that will write to the buffer (the writer), and only one task or * interrupt that will read from the buffer (the reader). It is safe for the * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers * then the application writer must place each call to a writing API function * (such as xStreamBufferSend()) inside a critical section and set the send * block time to 0. Likewise, if there are to be multiple different readers * then the application writer must place each call to a reading API function * (such as xStreamBufferReceive()) inside a critical section and set the receive * block time to 0. * * Use xStreamBufferReceive() to read from a stream buffer from a task. Use * xStreamBufferReceiveFromISR() to read from a stream buffer from an * interrupt service routine (ISR). * * @param xStreamBuffer The handle of the stream buffer from which bytes are to * be received. * * @param pvRxData A pointer to the buffer into which the received bytes will be * copied. * * @param xBufferLengthBytes The length of the buffer pointed to by the * pvRxData parameter. This sets the maximum number of bytes to receive in one * call. xStreamBufferReceive will return as many bytes as possible up to a * maximum set by xBufferLengthBytes. * * @param xTicksToWait The maximum amount of time the task should remain in the * Blocked state to wait for data to become available if the stream buffer is * empty. xStreamBufferReceive() will return immediately if xTicksToWait is * zero. The block time is specified in tick periods, so the absolute time it * represents is dependent on the tick frequency. The macro pdMS_TO_TICKS() can * be used to convert a time specified in milliseconds into a time specified in * ticks. Setting xTicksToWait to portMAX_DELAY will cause the task to wait * indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1 * in FreeRTOSConfig.h. A task does not use any CPU time when it is in the * Blocked state. * * @return The number of bytes actually read from the stream buffer, which will * be less than xBufferLengthBytes if the call to xStreamBufferReceive() timed * out before xBufferLengthBytes were available. * * Example use: * @code{c} * void vAFunction( StreamBuffer_t xStreamBuffer ) * { * uint8_t ucRxData[ 20 ]; * size_t xReceivedBytes; * const TickType_t xBlockTime = pdMS_TO_TICKS( 20 ); * * // Receive up to another sizeof( ucRxData ) bytes from the stream buffer. * // Wait in the Blocked state (so not using any CPU processing time) for a * // maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be * // available. * xReceivedBytes = xStreamBufferReceive( xStreamBuffer, * ( void * ) ucRxData, * sizeof( ucRxData ), * xBlockTime ); * * if( xReceivedBytes > 0 ) * { * // A ucRxData contains another xReceivedBytes bytes of data, which can * // be processed here.... * } * } * @endcode * \defgroup xStreamBufferReceive xStreamBufferReceive * \ingroup StreamBufferManagement */ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void * pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** * stream_buffer.h * * @code{c} * size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, * void *pvRxData, * size_t xBufferLengthBytes, * BaseType_t *pxHigherPriorityTaskWoken ); * @endcode * * An interrupt safe version of the API function that receives bytes from a * stream buffer. * * Use xStreamBufferReceive() to read bytes from a stream buffer from a task. * Use xStreamBufferReceiveFromISR() to read bytes from a stream buffer from an * interrupt service routine (ISR). * * @param xStreamBuffer The handle of the stream buffer from which a stream * is being received. * * @param pvRxData A pointer to the buffer into which the received bytes are * copied. * * @param xBufferLengthBytes The length of the buffer pointed to by the * pvRxData parameter. This sets the maximum number of bytes to receive in one * call. xStreamBufferReceive will return as many bytes as possible up to a * maximum set by xBufferLengthBytes. * * @param pxHigherPriorityTaskWoken It is possible that a stream buffer will * have a task blocked on it waiting for space to become available. Calling * xStreamBufferReceiveFromISR() can make space available, and so cause a task * that is waiting for space to leave the Blocked state. If calling * xStreamBufferReceiveFromISR() causes a task to leave the Blocked state, and * the unblocked task has a priority higher than the currently executing task * (the task that was interrupted), then, internally, * xStreamBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE. * If xStreamBufferReceiveFromISR() sets this value to pdTRUE, then normally a * context switch should be performed before the interrupt is exited. That will * ensure the interrupt returns directly to the highest priority Ready state * task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is * passed into the function. See the code example below for an example. * * @return The number of bytes read from the stream buffer, if any. * * Example use: * @code{c} * // A stream buffer that has already been created. * StreamBuffer_t xStreamBuffer; * * void vAnInterruptServiceRoutine( void ) * { * uint8_t ucRxData[ 20 ]; * size_t xReceivedBytes; * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. * * // Receive the next stream from the stream buffer. * xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer, * ( void * ) ucRxData, * sizeof( ucRxData ), * &xHigherPriorityTaskWoken ); * * if( xReceivedBytes > 0 ) * { * // ucRxData contains xReceivedBytes read from the stream buffer. * // Process the stream here.... * } * * // If xHigherPriorityTaskWoken was set to pdTRUE inside * // xStreamBufferReceiveFromISR() then a task that has a priority above the * // priority of the currently executing task was unblocked and a context * // switch should be performed to ensure the ISR returns to the unblocked * // task. In most FreeRTOS ports this is done by simply passing * // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the * // variables value, and perform the context switch if necessary. Check the * // documentation for the port in use for port specific instructions. * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * } * @endcode * \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR * \ingroup StreamBufferManagement */ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, void * pvRxData, size_t xBufferLengthBytes, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; /** * stream_buffer.h * * @code{c} * void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ); * @endcode * * Deletes a stream buffer that was previously created using a call to * xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream * buffer was created using dynamic memory (that is, by xStreamBufferCreate()), * then the allocated memory is freed. * * A stream buffer handle must not be used after the stream buffer has been * deleted. * * @param xStreamBuffer The handle of the stream buffer to be deleted. * * \defgroup vStreamBufferDelete vStreamBufferDelete * \ingroup StreamBufferManagement */ void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** * stream_buffer.h * * @code{c} * BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ); * @endcode * * Queries a stream buffer to see if it is full. A stream buffer is full if it * does not have any free space, and therefore cannot accept any more data. * * @param xStreamBuffer The handle of the stream buffer being queried. * * @return If the stream buffer is full then pdTRUE is returned. Otherwise * pdFALSE is returned. * * \defgroup xStreamBufferIsFull xStreamBufferIsFull * \ingroup StreamBufferManagement */ BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** * stream_buffer.h * * @code{c} * BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ); * @endcode * * Queries a stream buffer to see if it is empty. A stream buffer is empty if * it does not contain any data. * * @param xStreamBuffer The handle of the stream buffer being queried. * * @return If the stream buffer is empty then pdTRUE is returned. Otherwise * pdFALSE is returned. * * \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty * \ingroup StreamBufferManagement */ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** * stream_buffer.h * * @code{c} * BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ); * @endcode * * Resets a stream buffer to its initial, empty, state. Any data that was in * the stream buffer is discarded. A stream buffer can only be reset if there * are no tasks blocked waiting to either send to or receive from the stream * buffer. * * @param xStreamBuffer The handle of the stream buffer being reset. * * @return If the stream buffer is reset then pdPASS is returned. If there was * a task blocked waiting to send to or read from the stream buffer then the * stream buffer is not reset and pdFAIL is returned. * * \defgroup xStreamBufferReset xStreamBufferReset * \ingroup StreamBufferManagement */ BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** * stream_buffer.h * * @code{c} * size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ); * @endcode * * Queries a stream buffer to see how much free space it contains, which is * equal to the amount of data that can be sent to the stream buffer before it * is full. * * @param xStreamBuffer The handle of the stream buffer being queried. * * @return The number of bytes that can be written to the stream buffer before * the stream buffer would be full. * * \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable * \ingroup StreamBufferManagement */ size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** * stream_buffer.h * * @code{c} * size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ); * @endcode * * Queries a stream buffer to see how much data it contains, which is equal to * the number of bytes that can be read from the stream buffer before the stream * buffer would be empty. * * @param xStreamBuffer The handle of the stream buffer being queried. * * @return The number of bytes that can be read from the stream buffer before * the stream buffer would be empty. * * \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable * \ingroup StreamBufferManagement */ size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** * stream_buffer.h * * @code{c} * BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ); * @endcode * * A stream buffer's trigger level is the number of bytes that must be in the * stream buffer before a task that is blocked on the stream buffer to * wait for data is moved out of the blocked state. For example, if a task is * blocked on a read of an empty stream buffer that has a trigger level of 1 * then the task will be unblocked when a single byte is written to the buffer * or the task's block time expires. As another example, if a task is blocked * on a read of an empty stream buffer that has a trigger level of 10 then the * task will not be unblocked until the stream buffer contains at least 10 bytes * or the task's block time expires. If a reading task's block time expires * before the trigger level is reached then the task will still receive however * many bytes are actually available. Setting a trigger level of 0 will result * in a trigger level of 1 being used. It is not valid to specify a trigger * level that is greater than the buffer size. * * A trigger level is set when the stream buffer is created, and can be modified * using xStreamBufferSetTriggerLevel(). * * @param xStreamBuffer The handle of the stream buffer being updated. * * @param xTriggerLevel The new trigger level for the stream buffer. * * @return If xTriggerLevel was less than or equal to the stream buffer's length * then the trigger level will be updated and pdTRUE is returned. Otherwise * pdFALSE is returned. * * \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel * \ingroup StreamBufferManagement */ BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) PRIVILEGED_FUNCTION; /** * stream_buffer.h * * @code{c} * BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ); * @endcode * * For advanced users only. * * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when * data is sent to a message buffer or stream buffer. If there was a task that * was blocked on the message or stream buffer waiting for data to arrive then * the sbSEND_COMPLETED() macro sends a notification to the task to remove it * from the Blocked state. xStreamBufferSendCompletedFromISR() does the same * thing. It is provided to enable application writers to implement their own * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME. * * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for * additional information. * * @param xStreamBuffer The handle of the stream buffer to which data was * written. * * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be * initialised to pdFALSE before it is passed into * xStreamBufferSendCompletedFromISR(). If calling * xStreamBufferSendCompletedFromISR() removes a task from the Blocked state, * and the task has a priority above the priority of the currently running task, * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a * context switch should be performed before exiting the ISR. * * @return If a task was removed from the Blocked state then pdTRUE is returned. * Otherwise pdFALSE is returned. * * \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR * \ingroup StreamBufferManagement */ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; /** * stream_buffer.h * * @code{c} * BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ); * @endcode * * For advanced users only. * * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when * data is read out of a message buffer or stream buffer. If there was a task * that was blocked on the message or stream buffer waiting for data to arrive * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to * remove it from the Blocked state. xStreamBufferReceiveCompletedFromISR() * does the same thing. It is provided to enable application writers to * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT * ANY OTHER TIME. * * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for * additional information. * * @param xStreamBuffer The handle of the stream buffer from which data was * read. * * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be * initialised to pdFALSE before it is passed into * xStreamBufferReceiveCompletedFromISR(). If calling * xStreamBufferReceiveCompletedFromISR() removes a task from the Blocked state, * and the task has a priority above the priority of the currently running task, * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a * context switch should be performed before exiting the ISR. * * @return If a task was removed from the Blocked state then pdTRUE is returned. * Otherwise pdFALSE is returned. * * \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR * \ingroup StreamBufferManagement */ BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; /* Functions below here are not part of the public API. */ StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION; StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION; size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; #if ( configUSE_TRACE_FACILITY == 1 ) void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION; UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; #endif /* *INDENT-OFF* */ #if defined( __cplusplus ) } #endif /* *INDENT-ON* */ #endif /* !defined( STREAM_BUFFER_H ) */ ================================================ FILE: FreeRTOS-comparison/include/task.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef INC_TASK_H #define INC_TASK_H #ifndef INC_FREERTOS_H #error "include FreeRTOS.h must appear in source files before include task.h" #endif #include "list.h" /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ /*----------------------------------------------------------- * MACROS AND DEFINITIONS *----------------------------------------------------------*/ /* * If tskKERNEL_VERSION_NUMBER ends with + it represents the version in development * after the numbered release. * * The tskKERNEL_VERSION_MAJOR, tskKERNEL_VERSION_MINOR, tskKERNEL_VERSION_BUILD * values will reflect the last released version number. */ #define tskKERNEL_VERSION_NUMBER "V10.5.1" #define tskKERNEL_VERSION_MAJOR 10 #define tskKERNEL_VERSION_MINOR 5 #define tskKERNEL_VERSION_BUILD 1 /* MPU region parameters passed in ulParameters * of MemoryRegion_t struct. */ #define tskMPU_REGION_READ_ONLY ( 1UL << 0UL ) #define tskMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define tskMPU_REGION_EXECUTE_NEVER ( 1UL << 2UL ) #define tskMPU_REGION_NORMAL_MEMORY ( 1UL << 3UL ) #define tskMPU_REGION_DEVICE_MEMORY ( 1UL << 4UL ) /* The direct to task notification feature used to have only a single notification * per task. Now there is an array of notifications per task that is dimensioned by * configTASK_NOTIFICATION_ARRAY_ENTRIES. For backward compatibility, any use of the * original direct to task notification defaults to using the first index in the * array. */ #define tskDEFAULT_INDEX_TO_NOTIFY ( 0 ) /** * task. h * * Type by which tasks are referenced. For example, a call to xTaskCreate * returns (via a pointer parameter) an TaskHandle_t variable that can then * be used as a parameter to vTaskDelete to delete the task. * * \defgroup TaskHandle_t TaskHandle_t * \ingroup Tasks */ struct tskTaskControlBlock; /* The old naming convention is used to prevent breaking kernel aware debuggers. */ typedef struct tskTaskControlBlock * TaskHandle_t; /* * Defines the prototype to which the application task hook function must * conform. */ typedef BaseType_t (* TaskHookFunction_t)( void * ); /* Task states returned by eTaskGetState. */ typedef enum { eRunning = 0, /* A task is querying the state of itself, so must be running. */ eReady, /* The task being queried is in a ready or pending ready list. */ eBlocked, /* The task being queried is in the Blocked state. */ eSuspended, /* The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */ eDeleted, /* The task being queried has been deleted, but its TCB has not yet been freed. */ eInvalid /* Used as an 'invalid state' value. */ } eTaskState; /* Actions that can be performed when vTaskNotify() is called. */ typedef enum { eNoAction = 0, /* Notify the task without updating its notify value. */ eSetBits, /* Set bits in the task's notification value. */ eIncrement, /* Increment the task's notification value. */ eSetValueWithOverwrite, /* Set the task's notification value to a specific value even if the previous value has not yet been read by the task. */ eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */ } eNotifyAction; /* * Used internally only. */ typedef struct xTIME_OUT { BaseType_t xOverflowCount; TickType_t xTimeOnEntering; } TimeOut_t; /* * Defines the memory ranges allocated to the task when an MPU is used. */ typedef struct xMEMORY_REGION { void * pvBaseAddress; uint32_t ulLengthInBytes; uint32_t ulParameters; } MemoryRegion_t; /* * Parameters required to create an MPU protected task. */ typedef struct xTASK_PARAMETERS { TaskFunction_t pvTaskCode; const char * pcName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ configSTACK_DEPTH_TYPE usStackDepth; void * pvParameters; UBaseType_t uxPriority; StackType_t * puxStackBuffer; MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ]; #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) StaticTask_t * const pxTaskBuffer; #endif } TaskParameters_t; /* Used with the uxTaskGetSystemState() function to return the state of each task * in the system. */ typedef struct xTASK_STATUS { TaskHandle_t xHandle; /* The handle of the task to which the rest of the information in the structure relates. */ const char * pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ UBaseType_t xTaskNumber; /* A number unique to the task. */ eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */ UBaseType_t uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */ UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */ configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See https://www.FreeRTOS.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */ StackType_t * pxStackBase; /* Points to the lowest address of the task's stack area. */ #if ( ( portSTACK_GROWTH > 0 ) && ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) StackType_t * pxTopOfStack; /* Points to the top address of the task's stack area. */ StackType_t * pxEndOfStack; /* Points to the end address of the task's stack area. */ #endif configSTACK_DEPTH_TYPE usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */ } TaskStatus_t; /* Possible return values for eTaskConfirmSleepModeStatus(). */ typedef enum { eAbortSleep = 0, /* A task has been made ready or a context switch pended since portSUPPRESS_TICKS_AND_SLEEP() was called - abort entering a sleep mode. */ eStandardSleep, /* Enter a sleep mode that will not last any longer than the expected idle time. */ #if ( INCLUDE_vTaskSuspend == 1 ) eNoTasksWaitingTimeout /* No tasks are waiting for a timeout so it is safe to enter a sleep mode that can only be exited by an external interrupt. */ #endif /* INCLUDE_vTaskSuspend */ } eSleepModeStatus; /** * Defines the priority used by the idle task. This must not be modified. * * \ingroup TaskUtils */ #define tskIDLE_PRIORITY ( ( UBaseType_t ) 0U ) /** * task. h * * Macro for forcing a context switch. * * \defgroup taskYIELD taskYIELD * \ingroup SchedulerControl */ #define taskYIELD() portYIELD() /** * task. h * * Macro to mark the start of a critical code region. Preemptive context * switches cannot occur when in a critical region. * * NOTE: This may alter the stack (depending on the portable implementation) * so must be used with care! * * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL * \ingroup SchedulerControl */ #define taskENTER_CRITICAL() portENTER_CRITICAL() #define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() /** * task. h * * Macro to mark the end of a critical code region. Preemptive context * switches cannot occur when in a critical region. * * NOTE: This may alter the stack (depending on the portable implementation) * so must be used with care! * * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL * \ingroup SchedulerControl */ #define taskEXIT_CRITICAL() portEXIT_CRITICAL() #define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) /** * task. h * * Macro to disable all maskable interrupts. * * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS * \ingroup SchedulerControl */ #define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() /** * task. h * * Macro to enable microcontroller interrupts. * * \defgroup taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS * \ingroup SchedulerControl */ #define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() /* Definitions returned by xTaskGetSchedulerState(). taskSCHEDULER_SUSPENDED is * 0 to generate more optimal code when configASSERT() is defined as the constant * is used in assert() statements. */ #define taskSCHEDULER_SUSPENDED ( ( BaseType_t ) 0 ) #define taskSCHEDULER_NOT_STARTED ( ( BaseType_t ) 1 ) #define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 ) /*----------------------------------------------------------- * TASK CREATION API *----------------------------------------------------------*/ /** * task. h * @code{c} * BaseType_t xTaskCreate( * TaskFunction_t pxTaskCode, * const char *pcName, * configSTACK_DEPTH_TYPE usStackDepth, * void *pvParameters, * UBaseType_t uxPriority, * TaskHandle_t *pxCreatedTask * ); * @endcode * * Create a new task and add it to the list of tasks that are ready to run. * * Internally, within the FreeRTOS implementation, tasks use two blocks of * memory. The first block is used to hold the task's data structures. The * second block is used by the task as its stack. If a task is created using * xTaskCreate() then both blocks of memory are automatically dynamically * allocated inside the xTaskCreate() function. (see * https://www.FreeRTOS.org/a00111.html). If a task is created using * xTaskCreateStatic() then the application writer must provide the required * memory. xTaskCreateStatic() therefore allows a task to be created without * using any dynamic memory allocation. * * See xTaskCreateStatic() for a version that does not use any dynamic memory * allocation. * * xTaskCreate() can only be used to create a task that has unrestricted * access to the entire microcontroller memory map. Systems that include MPU * support can alternatively create an MPU constrained task using * xTaskCreateRestricted(). * * @param pxTaskCode Pointer to the task entry function. Tasks * must be implemented to never return (i.e. continuous loop). * * @param pcName A descriptive name for the task. This is mainly used to * facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN - default * is 16. * * @param usStackDepth The size of the task stack specified as the number of * variables the stack can hold - not the number of bytes. For example, if * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes * will be allocated for stack storage. * * @param pvParameters Pointer that will be used as the parameter for the task * being created. * * @param uxPriority The priority at which the task should run. Systems that * include MPU support can optionally create tasks in a privileged (system) * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For * example, to create a privileged task at priority 2 the uxPriority parameter * should be set to ( 2 | portPRIVILEGE_BIT ). * * @param pxCreatedTask Used to pass back a handle by which the created task * can be referenced. * * @return pdPASS if the task was successfully created and added to a ready * list, otherwise an error code defined in the file projdefs.h * * Example usage: * @code{c} * // Task to be created. * void vTaskCode( void * pvParameters ) * { * for( ;; ) * { * // Task code goes here. * } * } * * // Function that creates a task. * void vOtherFunction( void ) * { * static uint8_t ucParameterToPass; * TaskHandle_t xHandle = NULL; * * // Create the task, storing the handle. Note that the passed parameter ucParameterToPass * // must exist for the lifetime of the task, so in this case is declared static. If it was just an * // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time * // the new task attempts to access it. * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle ); * configASSERT( xHandle ); * * // Use the handle to delete the task. * if( xHandle != NULL ) * { * vTaskDelete( xHandle ); * } * } * @endcode * \defgroup xTaskCreate xTaskCreate * \ingroup Tasks */ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const configSTACK_DEPTH_TYPE usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; #endif /** * task. h * @code{c} * TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, * const char *pcName, * uint32_t ulStackDepth, * void *pvParameters, * UBaseType_t uxPriority, * StackType_t *puxStackBuffer, * StaticTask_t *pxTaskBuffer ); * @endcode * * Create a new task and add it to the list of tasks that are ready to run. * * Internally, within the FreeRTOS implementation, tasks use two blocks of * memory. The first block is used to hold the task's data structures. The * second block is used by the task as its stack. If a task is created using * xTaskCreate() then both blocks of memory are automatically dynamically * allocated inside the xTaskCreate() function. (see * https://www.FreeRTOS.org/a00111.html). If a task is created using * xTaskCreateStatic() then the application writer must provide the required * memory. xTaskCreateStatic() therefore allows a task to be created without * using any dynamic memory allocation. * * @param pxTaskCode Pointer to the task entry function. Tasks * must be implemented to never return (i.e. continuous loop). * * @param pcName A descriptive name for the task. This is mainly used to * facilitate debugging. The maximum length of the string is defined by * configMAX_TASK_NAME_LEN in FreeRTOSConfig.h. * * @param ulStackDepth The size of the task stack specified as the number of * variables the stack can hold - not the number of bytes. For example, if * the stack is 32-bits wide and ulStackDepth is defined as 100 then 400 bytes * will be allocated for stack storage. * * @param pvParameters Pointer that will be used as the parameter for the task * being created. * * @param uxPriority The priority at which the task will run. * * @param puxStackBuffer Must point to a StackType_t array that has at least * ulStackDepth indexes - the array will then be used as the task's stack, * removing the need for the stack to be allocated dynamically. * * @param pxTaskBuffer Must point to a variable of type StaticTask_t, which will * then be used to hold the task's data structures, removing the need for the * memory to be allocated dynamically. * * @return If neither puxStackBuffer nor pxTaskBuffer are NULL, then the task * will be created and a handle to the created task is returned. If either * puxStackBuffer or pxTaskBuffer are NULL then the task will not be created and * NULL is returned. * * Example usage: * @code{c} * * // Dimensions of the buffer that the task being created will use as its stack. * // NOTE: This is the number of words the stack will hold, not the number of * // bytes. For example, if each stack item is 32-bits, and this is set to 100, * // then 400 bytes (100 * 32-bits) will be allocated. #define STACK_SIZE 200 * * // Structure that will hold the TCB of the task being created. * StaticTask_t xTaskBuffer; * * // Buffer that the task being created will use as its stack. Note this is * // an array of StackType_t variables. The size of StackType_t is dependent on * // the RTOS port. * StackType_t xStack[ STACK_SIZE ]; * * // Function that implements the task being created. * void vTaskCode( void * pvParameters ) * { * // The parameter value is expected to be 1 as 1 is passed in the * // pvParameters value in the call to xTaskCreateStatic(). * configASSERT( ( uint32_t ) pvParameters == 1UL ); * * for( ;; ) * { * // Task code goes here. * } * } * * // Function that creates a task. * void vOtherFunction( void ) * { * TaskHandle_t xHandle = NULL; * * // Create the task without using any dynamic memory allocation. * xHandle = xTaskCreateStatic( * vTaskCode, // Function that implements the task. * "NAME", // Text name for the task. * STACK_SIZE, // Stack size in words, not bytes. * ( void * ) 1, // Parameter passed into the task. * tskIDLE_PRIORITY,// Priority at which the task is created. * xStack, // Array to use as the task's stack. * &xTaskBuffer ); // Variable to hold the task's data structure. * * // puxStackBuffer and pxTaskBuffer were not NULL, so the task will have * // been created, and xHandle will be the task's handle. Use the handle * // to suspend the task. * vTaskSuspend( xHandle ); * } * @endcode * \defgroup xTaskCreateStatic xTaskCreateStatic * \ingroup Tasks */ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION; #endif /* configSUPPORT_STATIC_ALLOCATION */ /** * task. h * @code{c} * BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask ); * @endcode * * Only available when configSUPPORT_DYNAMIC_ALLOCATION is set to 1. * * xTaskCreateRestricted() should only be used in systems that include an MPU * implementation. * * Create a new task and add it to the list of tasks that are ready to run. * The function parameters define the memory regions and associated access * permissions allocated to the task. * * See xTaskCreateRestrictedStatic() for a version that does not use any * dynamic memory allocation. * * @param pxTaskDefinition Pointer to a structure that contains a member * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API * documentation) plus an optional stack buffer and the memory region * definitions. * * @param pxCreatedTask Used to pass back a handle by which the created task * can be referenced. * * @return pdPASS if the task was successfully created and added to a ready * list, otherwise an error code defined in the file projdefs.h * * Example usage: * @code{c} * // Create an TaskParameters_t structure that defines the task to be created. * static const TaskParameters_t xCheckTaskParameters = * { * vATask, // pvTaskCode - the function that implements the task. * "ATask", // pcName - just a text name for the task to assist debugging. * 100, // usStackDepth - the stack size DEFINED IN WORDS. * NULL, // pvParameters - passed into the task function as the function parameters. * ( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state. * cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack. * * // xRegions - Allocate up to three separate memory regions for access by * // the task, with appropriate access permissions. Different processors have * // different memory alignment requirements - refer to the FreeRTOS documentation * // for full information. * { * // Base address Length Parameters * { cReadWriteArray, 32, portMPU_REGION_READ_WRITE }, * { cReadOnlyArray, 32, portMPU_REGION_READ_ONLY }, * { cPrivilegedOnlyAccessArray, 128, portMPU_REGION_PRIVILEGED_READ_WRITE } * } * }; * * int main( void ) * { * TaskHandle_t xHandle; * * // Create a task from the const structure defined above. The task handle * // is requested (the second parameter is not NULL) but in this case just for * // demonstration purposes as its not actually used. * xTaskCreateRestricted( &xRegTest1Parameters, &xHandle ); * * // Start the scheduler. * vTaskStartScheduler(); * * // Will only get here if there was insufficient memory to create the idle * // and/or timer task. * for( ;; ); * } * @endcode * \defgroup xTaskCreateRestricted xTaskCreateRestricted * \ingroup Tasks */ #if ( portUSING_MPU_WRAPPERS == 1 ) BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION; #endif /** * task. h * @code{c} * BaseType_t xTaskCreateRestrictedStatic( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask ); * @endcode * * Only available when configSUPPORT_STATIC_ALLOCATION is set to 1. * * xTaskCreateRestrictedStatic() should only be used in systems that include an * MPU implementation. * * Internally, within the FreeRTOS implementation, tasks use two blocks of * memory. The first block is used to hold the task's data structures. The * second block is used by the task as its stack. If a task is created using * xTaskCreateRestricted() then the stack is provided by the application writer, * and the memory used to hold the task's data structure is automatically * dynamically allocated inside the xTaskCreateRestricted() function. If a task * is created using xTaskCreateRestrictedStatic() then the application writer * must provide the memory used to hold the task's data structures too. * xTaskCreateRestrictedStatic() therefore allows a memory protected task to be * created without using any dynamic memory allocation. * * @param pxTaskDefinition Pointer to a structure that contains a member * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API * documentation) plus an optional stack buffer and the memory region * definitions. If configSUPPORT_STATIC_ALLOCATION is set to 1 the structure * contains an additional member, which is used to point to a variable of type * StaticTask_t - which is then used to hold the task's data structure. * * @param pxCreatedTask Used to pass back a handle by which the created task * can be referenced. * * @return pdPASS if the task was successfully created and added to a ready * list, otherwise an error code defined in the file projdefs.h * * Example usage: * @code{c} * // Create an TaskParameters_t structure that defines the task to be created. * // The StaticTask_t variable is only included in the structure when * // configSUPPORT_STATIC_ALLOCATION is set to 1. The PRIVILEGED_DATA macro can * // be used to force the variable into the RTOS kernel's privileged data area. * static PRIVILEGED_DATA StaticTask_t xTaskBuffer; * static const TaskParameters_t xCheckTaskParameters = * { * vATask, // pvTaskCode - the function that implements the task. * "ATask", // pcName - just a text name for the task to assist debugging. * 100, // usStackDepth - the stack size DEFINED IN WORDS. * NULL, // pvParameters - passed into the task function as the function parameters. * ( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state. * cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack. * * // xRegions - Allocate up to three separate memory regions for access by * // the task, with appropriate access permissions. Different processors have * // different memory alignment requirements - refer to the FreeRTOS documentation * // for full information. * { * // Base address Length Parameters * { cReadWriteArray, 32, portMPU_REGION_READ_WRITE }, * { cReadOnlyArray, 32, portMPU_REGION_READ_ONLY }, * { cPrivilegedOnlyAccessArray, 128, portMPU_REGION_PRIVILEGED_READ_WRITE } * } * * &xTaskBuffer; // Holds the task's data structure. * }; * * int main( void ) * { * TaskHandle_t xHandle; * * // Create a task from the const structure defined above. The task handle * // is requested (the second parameter is not NULL) but in this case just for * // demonstration purposes as its not actually used. * xTaskCreateRestrictedStatic( &xRegTest1Parameters, &xHandle ); * * // Start the scheduler. * vTaskStartScheduler(); * * // Will only get here if there was insufficient memory to create the idle * // and/or timer task. * for( ;; ); * } * @endcode * \defgroup xTaskCreateRestrictedStatic xTaskCreateRestrictedStatic * \ingroup Tasks */ #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION; #endif /** * task. h * @code{c} * void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ); * @endcode * * Memory regions are assigned to a restricted task when the task is created by * a call to xTaskCreateRestricted(). These regions can be redefined using * vTaskAllocateMPURegions(). * * @param xTask The handle of the task being updated. * * @param xRegions A pointer to a MemoryRegion_t structure that contains the * new memory region definitions. * * Example usage: * @code{c} * // Define an array of MemoryRegion_t structures that configures an MPU region * // allowing read/write access for 1024 bytes starting at the beginning of the * // ucOneKByte array. The other two of the maximum 3 definable regions are * // unused so set to zero. * static const MemoryRegion_t xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] = * { * // Base address Length Parameters * { ucOneKByte, 1024, portMPU_REGION_READ_WRITE }, * { 0, 0, 0 }, * { 0, 0, 0 } * }; * * void vATask( void *pvParameters ) * { * // This task was created such that it has access to certain regions of * // memory as defined by the MPU configuration. At some point it is * // desired that these MPU regions are replaced with that defined in the * // xAltRegions const struct above. Use a call to vTaskAllocateMPURegions() * // for this purpose. NULL is used as the task handle to indicate that this * // function should modify the MPU regions of the calling task. * vTaskAllocateMPURegions( NULL, xAltRegions ); * * // Now the task can continue its function, but from this point on can only * // access its stack and the ucOneKByte array (unless any other statically * // defined or shared regions have been declared elsewhere). * } * @endcode * \defgroup vTaskAllocateMPURegions vTaskAllocateMPURegions * \ingroup Tasks */ void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * void vTaskDelete( TaskHandle_t xTaskToDelete ); * @endcode * * INCLUDE_vTaskDelete must be defined as 1 for this function to be available. * See the configuration section for more information. * * Remove a task from the RTOS real time kernel's management. The task being * deleted will be removed from all ready, blocked, suspended and event lists. * * NOTE: The idle task is responsible for freeing the kernel allocated * memory from tasks that have been deleted. It is therefore important that * the idle task is not starved of microcontroller processing time if your * application makes any calls to vTaskDelete (). Memory allocated by the * task code is not automatically freed, and should be freed before the task * is deleted. * * See the demo application file death.c for sample code that utilises * vTaskDelete (). * * @param xTaskToDelete The handle of the task to be deleted. Passing NULL will * cause the calling task to be deleted. * * Example usage: * @code{c} * void vOtherFunction( void ) * { * TaskHandle_t xHandle; * * // Create the task, storing the handle. * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); * * // Use the handle to delete the task. * vTaskDelete( xHandle ); * } * @endcode * \defgroup vTaskDelete vTaskDelete * \ingroup Tasks */ void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; /*----------------------------------------------------------- * TASK CONTROL API *----------------------------------------------------------*/ /** * task. h * @code{c} * void vTaskDelay( const TickType_t xTicksToDelay ); * @endcode * * Delay a task for a given number of ticks. The actual time that the * task remains blocked depends on the tick rate. The constant * portTICK_PERIOD_MS can be used to calculate real time from the tick * rate - with the resolution of one tick period. * * INCLUDE_vTaskDelay must be defined as 1 for this function to be available. * See the configuration section for more information. * * * vTaskDelay() specifies a time at which the task wishes to unblock relative to * the time at which vTaskDelay() is called. For example, specifying a block * period of 100 ticks will cause the task to unblock 100 ticks after * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method * of controlling the frequency of a periodic task as the path taken through the * code, as well as other task and interrupt activity, will affect the frequency * at which vTaskDelay() gets called and therefore the time at which the task * next executes. See xTaskDelayUntil() for an alternative API function designed * to facilitate fixed frequency execution. It does this by specifying an * absolute time (rather than a relative time) at which the calling task should * unblock. * * @param xTicksToDelay The amount of time, in tick periods, that * the calling task should block. * * Example usage: * * void vTaskFunction( void * pvParameters ) * { * // Block for 500ms. * const TickType_t xDelay = 500 / portTICK_PERIOD_MS; * * for( ;; ) * { * // Simply toggle the LED every 500ms, blocking between each toggle. * vToggleLED(); * vTaskDelay( xDelay ); * } * } * * \defgroup vTaskDelay vTaskDelay * \ingroup TaskCtrl */ void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * BaseType_t xTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement ); * @endcode * * INCLUDE_xTaskDelayUntil must be defined as 1 for this function to be available. * See the configuration section for more information. * * Delay a task until a specified time. This function can be used by periodic * tasks to ensure a constant execution frequency. * * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will * cause a task to block for the specified number of ticks from the time vTaskDelay () is * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed * execution frequency as the time between a task starting to execute and that task * calling vTaskDelay () may not be fixed [the task may take a different path though the * code between calls, or may get interrupted or preempted a different number of times * each time it executes]. * * Whereas vTaskDelay () specifies a wake time relative to the time at which the function * is called, xTaskDelayUntil () specifies the absolute (exact) time at which it wishes to * unblock. * * The macro pdMS_TO_TICKS() can be used to calculate the number of ticks from a * time specified in milliseconds with a resolution of one tick period. * * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the * task was last unblocked. The variable must be initialised with the current time * prior to its first use (see the example below). Following this the variable is * automatically updated within xTaskDelayUntil (). * * @param xTimeIncrement The cycle time period. The task will be unblocked at * time *pxPreviousWakeTime + xTimeIncrement. Calling xTaskDelayUntil with the * same xTimeIncrement parameter value will cause the task to execute with * a fixed interface period. * * @return Value which can be used to check whether the task was actually delayed. * Will be pdTRUE if the task way delayed and pdFALSE otherwise. A task will not * be delayed if the next expected wake time is in the past. * * Example usage: * @code{c} * // Perform an action every 10 ticks. * void vTaskFunction( void * pvParameters ) * { * TickType_t xLastWakeTime; * const TickType_t xFrequency = 10; * BaseType_t xWasDelayed; * * // Initialise the xLastWakeTime variable with the current time. * xLastWakeTime = xTaskGetTickCount (); * for( ;; ) * { * // Wait for the next cycle. * xWasDelayed = xTaskDelayUntil( &xLastWakeTime, xFrequency ); * * // Perform action here. xWasDelayed value can be used to determine * // whether a deadline was missed if the code here took too long. * } * } * @endcode * \defgroup xTaskDelayUntil xTaskDelayUntil * \ingroup TaskCtrl */ BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) PRIVILEGED_FUNCTION; /* * vTaskDelayUntil() is the older version of xTaskDelayUntil() and does not * return a value. */ #define vTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ) \ do { \ ( void ) xTaskDelayUntil( ( pxPreviousWakeTime ), ( xTimeIncrement ) ); \ } while( 0 ) /** * task. h * @code{c} * BaseType_t xTaskAbortDelay( TaskHandle_t xTask ); * @endcode * * INCLUDE_xTaskAbortDelay must be defined as 1 in FreeRTOSConfig.h for this * function to be available. * * A task will enter the Blocked state when it is waiting for an event. The * event it is waiting for can be a temporal event (waiting for a time), such * as when vTaskDelay() is called, or an event on an object, such as when * xQueueReceive() or ulTaskNotifyTake() is called. If the handle of a task * that is in the Blocked state is used in a call to xTaskAbortDelay() then the * task will leave the Blocked state, and return from whichever function call * placed the task into the Blocked state. * * There is no 'FromISR' version of this function as an interrupt would need to * know which object a task was blocked on in order to know which actions to * take. For example, if the task was blocked on a queue the interrupt handler * would then need to know if the queue was locked. * * @param xTask The handle of the task to remove from the Blocked state. * * @return If the task referenced by xTask was not in the Blocked state then * pdFAIL is returned. Otherwise pdPASS is returned. * * \defgroup xTaskAbortDelay xTaskAbortDelay * \ingroup TaskCtrl */ BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ); * @endcode * * INCLUDE_uxTaskPriorityGet must be defined as 1 for this function to be available. * See the configuration section for more information. * * Obtain the priority of any task. * * @param xTask Handle of the task to be queried. Passing a NULL * handle results in the priority of the calling task being returned. * * @return The priority of xTask. * * Example usage: * @code{c} * void vAFunction( void ) * { * TaskHandle_t xHandle; * * // Create a task, storing the handle. * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); * * // ... * * // Use the handle to obtain the priority of the created task. * // It was created with tskIDLE_PRIORITY, but may have changed * // it itself. * if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY ) * { * // The task has changed it's priority. * } * * // ... * * // Is our priority higher than the created task? * if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) ) * { * // Our priority (obtained using NULL handle) is higher. * } * } * @endcode * \defgroup uxTaskPriorityGet uxTaskPriorityGet * \ingroup TaskCtrl */ UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ); * @endcode * * A version of uxTaskPriorityGet() that can be used from an ISR. */ UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * eTaskState eTaskGetState( TaskHandle_t xTask ); * @endcode * * INCLUDE_eTaskGetState must be defined as 1 for this function to be available. * See the configuration section for more information. * * Obtain the state of any task. States are encoded by the eTaskState * enumerated type. * * @param xTask Handle of the task to be queried. * * @return The state of xTask at the time the function was called. Note the * state of the task might change between the function being called, and the * functions return value being tested by the calling task. */ eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ); * @endcode * * configUSE_TRACE_FACILITY must be defined as 1 for this function to be * available. See the configuration section for more information. * * Populates a TaskStatus_t structure with information about a task. * * @param xTask Handle of the task being queried. If xTask is NULL then * information will be returned about the calling task. * * @param pxTaskStatus A pointer to the TaskStatus_t structure that will be * filled with information about the task referenced by the handle passed using * the xTask parameter. * * @param xGetFreeStackSpace The TaskStatus_t structure contains a member to report * the stack high water mark of the task being queried. Calculating the stack * high water mark takes a relatively long time, and can make the system * temporarily unresponsive - so the xGetFreeStackSpace parameter is provided to * allow the high water mark checking to be skipped. The high watermark value * will only be written to the TaskStatus_t structure if xGetFreeStackSpace is * not set to pdFALSE; * * @param eState The TaskStatus_t structure contains a member to report the * state of the task being queried. Obtaining the task state is not as fast as * a simple assignment - so the eState parameter is provided to allow the state * information to be omitted from the TaskStatus_t structure. To obtain state * information then set eState to eInvalid - otherwise the value passed in * eState will be reported as the task state in the TaskStatus_t structure. * * Example usage: * @code{c} * void vAFunction( void ) * { * TaskHandle_t xHandle; * TaskStatus_t xTaskDetails; * * // Obtain the handle of a task from its name. * xHandle = xTaskGetHandle( "Task_Name" ); * * // Check the handle is not NULL. * configASSERT( xHandle ); * * // Use the handle to obtain further information about the task. * vTaskGetInfo( xHandle, * &xTaskDetails, * pdTRUE, // Include the high water mark in xTaskDetails. * eInvalid ); // Include the task state in xTaskDetails. * } * @endcode * \defgroup vTaskGetInfo vTaskGetInfo * \ingroup TaskCtrl */ void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t * pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ); * @endcode * * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available. * See the configuration section for more information. * * Set the priority of any task. * * A context switch will occur before the function returns if the priority * being set is higher than the currently executing task. * * @param xTask Handle to the task for which the priority is being set. * Passing a NULL handle results in the priority of the calling task being set. * * @param uxNewPriority The priority to which the task will be set. * * Example usage: * @code{c} * void vAFunction( void ) * { * TaskHandle_t xHandle; * * // Create a task, storing the handle. * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); * * // ... * * // Use the handle to raise the priority of the created task. * vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 ); * * // ... * * // Use a NULL handle to raise our priority to the same value. * vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 ); * } * @endcode * \defgroup vTaskPrioritySet vTaskPrioritySet * \ingroup TaskCtrl */ void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * void vTaskSuspend( TaskHandle_t xTaskToSuspend ); * @endcode * * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. * See the configuration section for more information. * * Suspend any task. When suspended a task will never get any microcontroller * processing time, no matter what its priority. * * Calls to vTaskSuspend are not accumulative - * i.e. calling vTaskSuspend () twice on the same task still only requires one * call to vTaskResume () to ready the suspended task. * * @param xTaskToSuspend Handle to the task being suspended. Passing a NULL * handle will cause the calling task to be suspended. * * Example usage: * @code{c} * void vAFunction( void ) * { * TaskHandle_t xHandle; * * // Create a task, storing the handle. * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); * * // ... * * // Use the handle to suspend the created task. * vTaskSuspend( xHandle ); * * // ... * * // The created task will not run during this period, unless * // another task calls vTaskResume( xHandle ). * * //... * * * // Suspend ourselves. * vTaskSuspend( NULL ); * * // We cannot get here unless another task calls vTaskResume * // with our handle as the parameter. * } * @endcode * \defgroup vTaskSuspend vTaskSuspend * \ingroup TaskCtrl */ void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * void vTaskResume( TaskHandle_t xTaskToResume ); * @endcode * * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. * See the configuration section for more information. * * Resumes a suspended task. * * A task that has been suspended by one or more calls to vTaskSuspend () * will be made available for running again by a single call to * vTaskResume (). * * @param xTaskToResume Handle to the task being readied. * * Example usage: * @code{c} * void vAFunction( void ) * { * TaskHandle_t xHandle; * * // Create a task, storing the handle. * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); * * // ... * * // Use the handle to suspend the created task. * vTaskSuspend( xHandle ); * * // ... * * // The created task will not run during this period, unless * // another task calls vTaskResume( xHandle ). * * //... * * * // Resume the suspended task ourselves. * vTaskResume( xHandle ); * * // The created task will once again get microcontroller processing * // time in accordance with its priority within the system. * } * @endcode * \defgroup vTaskResume vTaskResume * \ingroup TaskCtrl */ void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * void xTaskResumeFromISR( TaskHandle_t xTaskToResume ); * @endcode * * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be * available. See the configuration section for more information. * * An implementation of vTaskResume() that can be called from within an ISR. * * A task that has been suspended by one or more calls to vTaskSuspend () * will be made available for running again by a single call to * xTaskResumeFromISR (). * * xTaskResumeFromISR() should not be used to synchronise a task with an * interrupt if there is a chance that the interrupt could arrive prior to the * task being suspended - as this can lead to interrupts being missed. Use of a * semaphore as a synchronisation mechanism would avoid this eventuality. * * @param xTaskToResume Handle to the task being readied. * * @return pdTRUE if resuming the task should result in a context switch, * otherwise pdFALSE. This is used by the ISR to determine if a context switch * may be required following the ISR. * * \defgroup vTaskResumeFromISR vTaskResumeFromISR * \ingroup TaskCtrl */ BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; /*----------------------------------------------------------- * SCHEDULER CONTROL *----------------------------------------------------------*/ /** * task. h * @code{c} * void vTaskStartScheduler( void ); * @endcode * * Starts the real time kernel tick processing. After calling the kernel * has control over which tasks are executed and when. * * See the demo application file main.c for an example of creating * tasks and starting the kernel. * * Example usage: * @code{c} * void vAFunction( void ) * { * // Create at least one task before starting the kernel. * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); * * // Start the real time kernel with preemption. * vTaskStartScheduler (); * * // Will not get here unless a task calls vTaskEndScheduler () * } * @endcode * * \defgroup vTaskStartScheduler vTaskStartScheduler * \ingroup SchedulerControl */ void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * void vTaskEndScheduler( void ); * @endcode * * NOTE: At the time of writing only the x86 real mode port, which runs on a PC * in place of DOS, implements this function. * * Stops the real time kernel tick. All created tasks will be automatically * deleted and multitasking (either preemptive or cooperative) will * stop. Execution then resumes from the point where vTaskStartScheduler () * was called, as if vTaskStartScheduler () had just returned. * * See the demo application file main. c in the demo/PC directory for an * example that uses vTaskEndScheduler (). * * vTaskEndScheduler () requires an exit function to be defined within the * portable layer (see vPortEndScheduler () in port. c for the PC port). This * performs hardware specific operations such as stopping the kernel tick. * * vTaskEndScheduler () will cause all of the resources allocated by the * kernel to be freed - but will not free resources allocated by application * tasks. * * Example usage: * @code{c} * void vTaskCode( void * pvParameters ) * { * for( ;; ) * { * // Task code goes here. * * // At some point we want to end the real time kernel processing * // so call ... * vTaskEndScheduler (); * } * } * * void vAFunction( void ) * { * // Create at least one task before starting the kernel. * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); * * // Start the real time kernel with preemption. * vTaskStartScheduler (); * * // Will only get here when the vTaskCode () task has called * // vTaskEndScheduler (). When we get here we are back to single task * // execution. * } * @endcode * * \defgroup vTaskEndScheduler vTaskEndScheduler * \ingroup SchedulerControl */ void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * void vTaskSuspendAll( void ); * @endcode * * Suspends the scheduler without disabling interrupts. Context switches will * not occur while the scheduler is suspended. * * After calling vTaskSuspendAll () the calling task will continue to execute * without risk of being swapped out until a call to xTaskResumeAll () has been * made. * * API functions that have the potential to cause a context switch (for example, * xTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler * is suspended. * * Example usage: * @code{c} * void vTask1( void * pvParameters ) * { * for( ;; ) * { * // Task code goes here. * * // ... * * // At some point the task wants to perform a long operation during * // which it does not want to get swapped out. It cannot use * // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the * // operation may cause interrupts to be missed - including the * // ticks. * * // Prevent the real time kernel swapping out the task. * vTaskSuspendAll (); * * // Perform the operation here. There is no need to use critical * // sections as we have all the microcontroller processing time. * // During this time interrupts will still operate and the kernel * // tick count will be maintained. * * // ... * * // The operation is complete. Restart the kernel. * xTaskResumeAll (); * } * } * @endcode * \defgroup vTaskSuspendAll vTaskSuspendAll * \ingroup SchedulerControl */ void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * BaseType_t xTaskResumeAll( void ); * @endcode * * Resumes scheduler activity after it was suspended by a call to * vTaskSuspendAll(). * * xTaskResumeAll() only resumes the scheduler. It does not unsuspend tasks * that were previously suspended by a call to vTaskSuspend(). * * @return If resuming the scheduler caused a context switch then pdTRUE is * returned, otherwise pdFALSE is returned. * * Example usage: * @code{c} * void vTask1( void * pvParameters ) * { * for( ;; ) * { * // Task code goes here. * * // ... * * // At some point the task wants to perform a long operation during * // which it does not want to get swapped out. It cannot use * // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the * // operation may cause interrupts to be missed - including the * // ticks. * * // Prevent the real time kernel swapping out the task. * vTaskSuspendAll (); * * // Perform the operation here. There is no need to use critical * // sections as we have all the microcontroller processing time. * // During this time interrupts will still operate and the real * // time kernel tick count will be maintained. * * // ... * * // The operation is complete. Restart the kernel. We want to force * // a context switch - but there is no point if resuming the scheduler * // caused a context switch already. * if( !xTaskResumeAll () ) * { * taskYIELD (); * } * } * } * @endcode * \defgroup xTaskResumeAll xTaskResumeAll * \ingroup SchedulerControl */ BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; /*----------------------------------------------------------- * TASK UTILITIES *----------------------------------------------------------*/ /** * task. h * @code{c} * TickType_t xTaskGetTickCount( void ); * @endcode * * @return The count of ticks since vTaskStartScheduler was called. * * \defgroup xTaskGetTickCount xTaskGetTickCount * \ingroup TaskUtils */ TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * TickType_t xTaskGetTickCountFromISR( void ); * @endcode * * @return The count of ticks since vTaskStartScheduler was called. * * This is a version of xTaskGetTickCount() that is safe to be called from an * ISR - provided that TickType_t is the natural word size of the * microcontroller being used or interrupt nesting is either not supported or * not being used. * * \defgroup xTaskGetTickCountFromISR xTaskGetTickCountFromISR * \ingroup TaskUtils */ TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * uint16_t uxTaskGetNumberOfTasks( void ); * @endcode * * @return The number of tasks that the real time kernel is currently managing. * This includes all ready, blocked and suspended tasks. A task that * has been deleted but not yet freed by the idle task will also be * included in the count. * * \defgroup uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks * \ingroup TaskUtils */ UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * char *pcTaskGetName( TaskHandle_t xTaskToQuery ); * @endcode * * @return The text (human readable) name of the task referenced by the handle * xTaskToQuery. A task can query its own name by either passing in its own * handle, or by setting xTaskToQuery to NULL. * * \defgroup pcTaskGetName pcTaskGetName * \ingroup TaskUtils */ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ /** * task. h * @code{c} * TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ); * @endcode * * NOTE: This function takes a relatively long time to complete and should be * used sparingly. * * @return The handle of the task that has the human readable name pcNameToQuery. * NULL is returned if no matching name is found. INCLUDE_xTaskGetHandle * must be set to 1 in FreeRTOSConfig.h for pcTaskGetHandle() to be available. * * \defgroup pcTaskGetHandle pcTaskGetHandle * \ingroup TaskUtils */ TaskHandle_t xTaskGetHandle( const char * pcNameToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ /** * task.h * @code{c} * UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ); * @endcode * * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for * this function to be available. * * Returns the high water mark of the stack associated with xTask. That is, * the minimum free stack space there has been (in words, so on a 32 bit machine * a value of 1 means 4 bytes) since the task started. The smaller the returned * number the closer the task has come to overflowing its stack. * * uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the * same except for their return type. Using configSTACK_DEPTH_TYPE allows the * user to determine the return type. It gets around the problem of the value * overflowing on 8-bit types without breaking backward compatibility for * applications that expect an 8-bit return type. * * @param xTask Handle of the task associated with the stack to be checked. * Set xTask to NULL to check the stack of the calling task. * * @return The smallest amount of free stack space there has been (in words, so * actual spaces on the stack rather than bytes) since the task referenced by * xTask was created. */ UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** * task.h * @code{c} * configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ); * @endcode * * INCLUDE_uxTaskGetStackHighWaterMark2 must be set to 1 in FreeRTOSConfig.h for * this function to be available. * * Returns the high water mark of the stack associated with xTask. That is, * the minimum free stack space there has been (in words, so on a 32 bit machine * a value of 1 means 4 bytes) since the task started. The smaller the returned * number the closer the task has come to overflowing its stack. * * uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the * same except for their return type. Using configSTACK_DEPTH_TYPE allows the * user to determine the return type. It gets around the problem of the value * overflowing on 8-bit types without breaking backward compatibility for * applications that expect an 8-bit return type. * * @param xTask Handle of the task associated with the stack to be checked. * Set xTask to NULL to check the stack of the calling task. * * @return The smallest amount of free stack space there has been (in words, so * actual spaces on the stack rather than bytes) since the task referenced by * xTask was created. */ configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /* When using trace macros it is sometimes necessary to include task.h before * FreeRTOS.h. When this is done TaskHookFunction_t will not yet have been defined, * so the following two prototypes will cause a compilation error. This can be * fixed by simply guarding against the inclusion of these two prototypes unless * they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration * constant. */ #ifdef configUSE_APPLICATION_TASK_TAG #if configUSE_APPLICATION_TASK_TAG == 1 /** * task.h * @code{c} * void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ); * @endcode * * Sets pxHookFunction to be the task hook function used by the task xTask. * Passing xTask as NULL has the effect of setting the calling tasks hook * function. */ void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) PRIVILEGED_FUNCTION; /** * task.h * @code{c} * void xTaskGetApplicationTaskTag( TaskHandle_t xTask ); * @endcode * * Returns the pxHookFunction value assigned to the task xTask. Do not * call from an interrupt service routine - call * xTaskGetApplicationTaskTagFromISR() instead. */ TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** * task.h * @code{c} * void xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ); * @endcode * * Returns the pxHookFunction value assigned to the task xTask. Can * be called from an interrupt service routine. */ TaskHookFunction_t xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; #endif /* configUSE_APPLICATION_TASK_TAG ==1 */ #endif /* ifdef configUSE_APPLICATION_TASK_TAG */ #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) /* Each task contains an array of pointers that is dimensioned by the * configNUM_THREAD_LOCAL_STORAGE_POINTERS setting in FreeRTOSConfig.h. The * kernel does not use the pointers itself, so the application writer can use * the pointers for any purpose they wish. The following two functions are * used to set and query a pointer respectively. */ void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void * pvValue ) PRIVILEGED_FUNCTION; void * pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) PRIVILEGED_FUNCTION; #endif #if ( configCHECK_FOR_STACK_OVERFLOW > 0 ) /** * task.h * @code{c} * void vApplicationStackOverflowHook( TaskHandle_t xTask char *pcTaskName); * @endcode * * The application stack overflow hook is called when a stack overflow is detected for a task. * * Details on stack overflow detection can be found here: https://www.FreeRTOS.org/Stacks-and-stack-overflow-checking.html * * @param xTask the task that just exceeded its stack boundaries. * @param pcTaskName A character string containing the name of the offending task. */ void vApplicationStackOverflowHook( TaskHandle_t xTask, char * pcTaskName ); #endif #if ( configUSE_TICK_HOOK > 0 ) /** * task.h * @code{c} * void vApplicationTickHook( void ); * @endcode * * This hook function is called in the system tick handler after any OS work is completed. */ void vApplicationTickHook( void ); /*lint !e526 Symbol not defined as it is an application callback. */ #endif #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) /** * task.h * @code{c} * void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) * @endcode * * This function is used to provide a statically allocated block of memory to FreeRTOS to hold the Idle Task TCB. This function is required when * configSUPPORT_STATIC_ALLOCATION is set. For more information see this URI: https://www.FreeRTOS.org/a00110.html#configSUPPORT_STATIC_ALLOCATION * * @param ppxIdleTaskTCBBuffer A handle to a statically allocated TCB buffer * @param ppxIdleTaskStackBuffer A handle to a statically allocated Stack buffer for the idle task * @param pulIdleTaskStackSize A pointer to the number of elements that will fit in the allocated stack buffer */ void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, uint32_t * pulIdleTaskStackSize ); /*lint !e526 Symbol not defined as it is an application callback. */ #endif /** * task.h * @code{c} * BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ); * @endcode * * Calls the hook function associated with xTask. Passing xTask as NULL has * the effect of calling the Running tasks (the calling task) hook function. * * pvParameter is passed to the hook function for the task to interpret as it * wants. The return value is the value returned by the task hook function * registered by the user. */ BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void * pvParameter ) PRIVILEGED_FUNCTION; /** * xTaskGetIdleTaskHandle() is only available if * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h. * * Simply returns the handle of the idle task. It is not valid to call * xTaskGetIdleTaskHandle() before the scheduler has been started. */ TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION; /** * configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for * uxTaskGetSystemState() to be available. * * uxTaskGetSystemState() populates an TaskStatus_t structure for each task in * the system. TaskStatus_t structures contain, among other things, members * for the task handle, task name, task priority, task state, and total amount * of run time consumed by the task. See the TaskStatus_t structure * definition in this file for the full member list. * * NOTE: This function is intended for debugging use only as its use results in * the scheduler remaining suspended for an extended period. * * @param pxTaskStatusArray A pointer to an array of TaskStatus_t structures. * The array must contain at least one TaskStatus_t structure for each task * that is under the control of the RTOS. The number of tasks under the control * of the RTOS can be determined using the uxTaskGetNumberOfTasks() API function. * * @param uxArraySize The size of the array pointed to by the pxTaskStatusArray * parameter. The size is specified as the number of indexes in the array, or * the number of TaskStatus_t structures contained in the array, not by the * number of bytes in the array. * * @param pulTotalRunTime If configGENERATE_RUN_TIME_STATS is set to 1 in * FreeRTOSConfig.h then *pulTotalRunTime is set by uxTaskGetSystemState() to the * total run time (as defined by the run time stats clock, see * https://www.FreeRTOS.org/rtos-run-time-stats.html) since the target booted. * pulTotalRunTime can be set to NULL to omit the total run time information. * * @return The number of TaskStatus_t structures that were populated by * uxTaskGetSystemState(). This should equal the number returned by the * uxTaskGetNumberOfTasks() API function, but will be zero if the value passed * in the uxArraySize parameter was too small. * * Example usage: * @code{c} * // This example demonstrates how a human readable table of run time stats * // information is generated from raw data provided by uxTaskGetSystemState(). * // The human readable table is written to pcWriteBuffer * void vTaskGetRunTimeStats( char *pcWriteBuffer ) * { * TaskStatus_t *pxTaskStatusArray; * volatile UBaseType_t uxArraySize, x; * configRUN_TIME_COUNTER_TYPE ulTotalRunTime, ulStatsAsPercentage; * * // Make sure the write buffer does not contain a string. * pcWriteBuffer = 0x00; * * // Take a snapshot of the number of tasks in case it changes while this * // function is executing. * uxArraySize = uxTaskGetNumberOfTasks(); * * // Allocate a TaskStatus_t structure for each task. An array could be * // allocated statically at compile time. * pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ) ); * * if( pxTaskStatusArray != NULL ) * { * // Generate raw status information about each task. * uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime ); * * // For percentage calculations. * ulTotalRunTime /= 100UL; * * // Avoid divide by zero errors. * if( ulTotalRunTime > 0 ) * { * // For each populated position in the pxTaskStatusArray array, * // format the raw data as human readable ASCII data * for( x = 0; x < uxArraySize; x++ ) * { * // What percentage of the total run time has the task used? * // This will always be rounded down to the nearest integer. * // ulTotalRunTimeDiv100 has already been divided by 100. * ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime; * * if( ulStatsAsPercentage > 0UL ) * { * sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage ); * } * else * { * // If the percentage is zero here then the task has * // consumed less than 1% of the total run time. * sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter ); * } * * pcWriteBuffer += strlen( ( char * ) pcWriteBuffer ); * } * } * * // The array is no longer needed, free the memory it consumes. * vPortFree( pxTaskStatusArray ); * } * } * @endcode */ UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * void vTaskList( char *pcWriteBuffer ); * @endcode * * configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS must * both be defined as 1 for this function to be available. See the * configuration section of the FreeRTOS.org website for more information. * * NOTE 1: This function will disable interrupts for its duration. It is * not intended for normal application runtime use but as a debug aid. * * Lists all the current tasks, along with their current state and stack * usage high water mark. * * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or * suspended ('S'). * * PLEASE NOTE: * * This function is provided for convenience only, and is used by many of the * demo applications. Do not consider it to be part of the scheduler. * * vTaskList() calls uxTaskGetSystemState(), then formats part of the * uxTaskGetSystemState() output into a human readable table that displays task: * names, states, priority, stack usage and task number. * Stack usage specified as the number of unused StackType_t words stack can hold * on top of stack - not the number of bytes. * * vTaskList() has a dependency on the sprintf() C library function that might * bloat the code size, use a lot of stack, and provide different results on * different platforms. An alternative, tiny, third party, and limited * functionality implementation of sprintf() is provided in many of the * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note * printf-stdarg.c does not provide a full snprintf() implementation!). * * It is recommended that production systems call uxTaskGetSystemState() * directly to get access to raw stats data, rather than indirectly through a * call to vTaskList(). * * @param pcWriteBuffer A buffer into which the above mentioned details * will be written, in ASCII form. This buffer is assumed to be large * enough to contain the generated report. Approximately 40 bytes per * task should be sufficient. * * \defgroup vTaskList vTaskList * \ingroup TaskUtils */ void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ /** * task. h * @code{c} * void vTaskGetRunTimeStats( char *pcWriteBuffer ); * @endcode * * configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS * must both be defined as 1 for this function to be available. The application * must also then provide definitions for * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() * to configure a peripheral timer/counter and return the timers current count * value respectively. The counter should be at least 10 times the frequency of * the tick count. * * NOTE 1: This function will disable interrupts for its duration. It is * not intended for normal application runtime use but as a debug aid. * * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total * accumulated execution time being stored for each task. The resolution * of the accumulated time value depends on the frequency of the timer * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. * Calling vTaskGetRunTimeStats() writes the total execution time of each * task into a buffer, both as an absolute count value and as a percentage * of the total system execution time. * * NOTE 2: * * This function is provided for convenience only, and is used by many of the * demo applications. Do not consider it to be part of the scheduler. * * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part of the * uxTaskGetSystemState() output into a human readable table that displays the * amount of time each task has spent in the Running state in both absolute and * percentage terms. * * vTaskGetRunTimeStats() has a dependency on the sprintf() C library function * that might bloat the code size, use a lot of stack, and provide different * results on different platforms. An alternative, tiny, third party, and * limited functionality implementation of sprintf() is provided in many of the * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note * printf-stdarg.c does not provide a full snprintf() implementation!). * * It is recommended that production systems call uxTaskGetSystemState() directly * to get access to raw stats data, rather than indirectly through a call to * vTaskGetRunTimeStats(). * * @param pcWriteBuffer A buffer into which the execution times will be * written, in ASCII form. This buffer is assumed to be large enough to * contain the generated report. Approximately 40 bytes per task should * be sufficient. * * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats * \ingroup TaskUtils */ void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ /** * task. h * @code{c} * configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ); * configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercent( void ); * @endcode * * configGENERATE_RUN_TIME_STATS, configUSE_STATS_FORMATTING_FUNCTIONS and * INCLUDE_xTaskGetIdleTaskHandle must all be defined as 1 for these functions * to be available. The application must also then provide definitions for * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() * to configure a peripheral timer/counter and return the timers current count * value respectively. The counter should be at least 10 times the frequency of * the tick count. * * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total * accumulated execution time being stored for each task. The resolution * of the accumulated time value depends on the frequency of the timer * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. * While uxTaskGetSystemState() and vTaskGetRunTimeStats() writes the total * execution time of each task into a buffer, ulTaskGetIdleRunTimeCounter() * returns the total execution time of just the idle task and * ulTaskGetIdleRunTimePercent() returns the percentage of the CPU time used by * just the idle task. * * Note the amount of idle time is only a good measure of the slack time in a * system if there are no other tasks executing at the idle priority, tickless * idle is not used, and configIDLE_SHOULD_YIELD is set to 0. * * @return The total run time of the idle task or the percentage of the total * run time consumed by the idle task. This is the amount of time the * idle task has actually been executing. The unit of time is dependent on the * frequency configured using the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and * portGET_RUN_TIME_COUNTER_VALUE() macros. * * \defgroup ulTaskGetIdleRunTimeCounter ulTaskGetIdleRunTimeCounter * \ingroup TaskUtils */ configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ) PRIVILEGED_FUNCTION; configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercent( void ) PRIVILEGED_FUNCTION; /** * task. h * @code{c} * BaseType_t xTaskNotifyIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction ); * BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction ); * @endcode * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these * functions to be available. * * Sends a direct to task notification to a task, with an optional value and * action. * * Each task has a private array of "notification values" (or 'notifications'), * each of which is a 32-bit unsigned integer (uint32_t). The constant * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the * array, and (for backward compatibility) defaults to 1 if left undefined. * Prior to FreeRTOS V10.4.0 there was only one notification value per task. * * Events can be sent to a task using an intermediary object. Examples of such * objects are queues, semaphores, mutexes and event groups. Task notifications * are a method of sending an event directly to a task without the need for such * an intermediary object. * * A notification sent to a task can optionally perform an action, such as * update, overwrite or increment one of the task's notification values. In * that way task notifications can be used to send data to a task, or be used as * light weight and fast binary or counting semaphores. * * A task can use xTaskNotifyWaitIndexed() or ulTaskNotifyTakeIndexed() to * [optionally] block to wait for a notification to be pending. The task does * not consume any CPU time while it is in the Blocked state. * * A notification sent to a task will remain pending until it is cleared by the * task calling xTaskNotifyWaitIndexed() or ulTaskNotifyTakeIndexed() (or their * un-indexed equivalents). If the task was already in the Blocked state to * wait for a notification when the notification arrives then the task will * automatically be removed from the Blocked state (unblocked) and the * notification cleared. * * **NOTE** Each notification within the array operates independently - a task * can only block on one notification within the array at a time and will not be * unblocked by a notification sent to any other array index. * * Backward compatibility information: * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and * all task notification API functions operated on that value. Replacing the * single notification value with an array of notification values necessitated a * new set of API functions that could address specific notifications within the * array. xTaskNotify() is the original API function, and remains backward * compatible by always operating on the notification value at index 0 in the * array. Calling xTaskNotify() is equivalent to calling xTaskNotifyIndexed() * with the uxIndexToNotify parameter set to 0. * * @param xTaskToNotify The handle of the task being notified. The handle to a * task can be returned from the xTaskCreate() API function used to create the * task, and the handle of the currently running task can be obtained by calling * xTaskGetCurrentTaskHandle(). * * @param uxIndexToNotify The index within the target task's array of * notification values to which the notification is to be sent. uxIndexToNotify * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. xTaskNotify() does * not have this parameter and always sends notifications to index 0. * * @param ulValue Data that can be sent with the notification. How the data is * used depends on the value of the eAction parameter. * * @param eAction Specifies how the notification updates the task's notification * value, if at all. Valid values for eAction are as follows: * * eSetBits - * The target notification value is bitwise ORed with ulValue. * xTaskNotifyIndexed() always returns pdPASS in this case. * * eIncrement - * The target notification value is incremented. ulValue is not used and * xTaskNotifyIndexed() always returns pdPASS in this case. * * eSetValueWithOverwrite - * The target notification value is set to the value of ulValue, even if the * task being notified had not yet processed the previous notification at the * same array index (the task already had a notification pending at that index). * xTaskNotifyIndexed() always returns pdPASS in this case. * * eSetValueWithoutOverwrite - * If the task being notified did not already have a notification pending at the * same array index then the target notification value is set to ulValue and * xTaskNotifyIndexed() will return pdPASS. If the task being notified already * had a notification pending at the same array index then no action is * performed and pdFAIL is returned. * * eNoAction - * The task receives a notification at the specified array index without the * notification value at that index being updated. ulValue is not used and * xTaskNotifyIndexed() always returns pdPASS in this case. * * pulPreviousNotificationValue - * Can be used to pass out the subject task's notification value before any * bits are modified by the notify function. * * @return Dependent on the value of eAction. See the description of the * eAction parameter. * * \defgroup xTaskNotifyIndexed xTaskNotifyIndexed * \ingroup TaskNotifications */ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t * pulPreviousNotificationValue ) PRIVILEGED_FUNCTION; #define xTaskNotify( xTaskToNotify, ulValue, eAction ) \ xTaskGenericNotify( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulValue ), ( eAction ), NULL ) #define xTaskNotifyIndexed( xTaskToNotify, uxIndexToNotify, ulValue, eAction ) \ xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), NULL ) /** * task. h * @code{c} * BaseType_t xTaskNotifyAndQueryIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue ); * BaseType_t xTaskNotifyAndQuery( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue ); * @endcode * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * * xTaskNotifyAndQueryIndexed() performs the same operation as * xTaskNotifyIndexed() with the addition that it also returns the subject * task's prior notification value (the notification value at the time the * function is called rather than when the function returns) in the additional * pulPreviousNotifyValue parameter. * * xTaskNotifyAndQuery() performs the same operation as xTaskNotify() with the * addition that it also returns the subject task's prior notification value * (the notification value as it was at the time the function is called, rather * than when the function returns) in the additional pulPreviousNotifyValue * parameter. * * \defgroup xTaskNotifyAndQueryIndexed xTaskNotifyAndQueryIndexed * \ingroup TaskNotifications */ #define xTaskNotifyAndQuery( xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue ) \ xTaskGenericNotify( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) ) #define xTaskNotifyAndQueryIndexed( xTaskToNotify, uxIndexToNotify, ulValue, eAction, pulPreviousNotifyValue ) \ xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) ) /** * task. h * @code{c} * BaseType_t xTaskNotifyIndexedFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken ); * @endcode * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these * functions to be available. * * A version of xTaskNotifyIndexed() that can be used from an interrupt service * routine (ISR). * * Each task has a private array of "notification values" (or 'notifications'), * each of which is a 32-bit unsigned integer (uint32_t). The constant * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the * array, and (for backward compatibility) defaults to 1 if left undefined. * Prior to FreeRTOS V10.4.0 there was only one notification value per task. * * Events can be sent to a task using an intermediary object. Examples of such * objects are queues, semaphores, mutexes and event groups. Task notifications * are a method of sending an event directly to a task without the need for such * an intermediary object. * * A notification sent to a task can optionally perform an action, such as * update, overwrite or increment one of the task's notification values. In * that way task notifications can be used to send data to a task, or be used as * light weight and fast binary or counting semaphores. * * A task can use xTaskNotifyWaitIndexed() to [optionally] block to wait for a * notification to be pending, or ulTaskNotifyTakeIndexed() to [optionally] block * to wait for a notification value to have a non-zero value. The task does * not consume any CPU time while it is in the Blocked state. * * A notification sent to a task will remain pending until it is cleared by the * task calling xTaskNotifyWaitIndexed() or ulTaskNotifyTakeIndexed() (or their * un-indexed equivalents). If the task was already in the Blocked state to * wait for a notification when the notification arrives then the task will * automatically be removed from the Blocked state (unblocked) and the * notification cleared. * * **NOTE** Each notification within the array operates independently - a task * can only block on one notification within the array at a time and will not be * unblocked by a notification sent to any other array index. * * Backward compatibility information: * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and * all task notification API functions operated on that value. Replacing the * single notification value with an array of notification values necessitated a * new set of API functions that could address specific notifications within the * array. xTaskNotifyFromISR() is the original API function, and remains * backward compatible by always operating on the notification value at index 0 * within the array. Calling xTaskNotifyFromISR() is equivalent to calling * xTaskNotifyIndexedFromISR() with the uxIndexToNotify parameter set to 0. * * @param uxIndexToNotify The index within the target task's array of * notification values to which the notification is to be sent. uxIndexToNotify * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. xTaskNotifyFromISR() * does not have this parameter and always sends notifications to index 0. * * @param xTaskToNotify The handle of the task being notified. The handle to a * task can be returned from the xTaskCreate() API function used to create the * task, and the handle of the currently running task can be obtained by calling * xTaskGetCurrentTaskHandle(). * * @param ulValue Data that can be sent with the notification. How the data is * used depends on the value of the eAction parameter. * * @param eAction Specifies how the notification updates the task's notification * value, if at all. Valid values for eAction are as follows: * * eSetBits - * The task's notification value is bitwise ORed with ulValue. xTaskNotify() * always returns pdPASS in this case. * * eIncrement - * The task's notification value is incremented. ulValue is not used and * xTaskNotify() always returns pdPASS in this case. * * eSetValueWithOverwrite - * The task's notification value is set to the value of ulValue, even if the * task being notified had not yet processed the previous notification (the * task already had a notification pending). xTaskNotify() always returns * pdPASS in this case. * * eSetValueWithoutOverwrite - * If the task being notified did not already have a notification pending then * the task's notification value is set to ulValue and xTaskNotify() will * return pdPASS. If the task being notified already had a notification * pending then no action is performed and pdFAIL is returned. * * eNoAction - * The task receives a notification without its notification value being * updated. ulValue is not used and xTaskNotify() always returns pdPASS in * this case. * * @param pxHigherPriorityTaskWoken xTaskNotifyFromISR() will set * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the * task to which the notification was sent to leave the Blocked state, and the * unblocked task has a priority higher than the currently running task. If * xTaskNotifyFromISR() sets this value to pdTRUE then a context switch should * be requested before the interrupt is exited. How a context switch is * requested from an ISR is dependent on the port - see the documentation page * for the port in use. * * @return Dependent on the value of eAction. See the description of the * eAction parameter. * * \defgroup xTaskNotifyIndexedFromISR xTaskNotifyIndexedFromISR * \ingroup TaskNotifications */ BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t * pulPreviousNotificationValue, BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; #define xTaskNotifyFromISR( xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) \ xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) ) #define xTaskNotifyIndexedFromISR( xTaskToNotify, uxIndexToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) \ xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) ) /** * task. h * @code{c} * BaseType_t xTaskNotifyAndQueryIndexedFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xTaskNotifyAndQueryFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ); * @endcode * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * * xTaskNotifyAndQueryIndexedFromISR() performs the same operation as * xTaskNotifyIndexedFromISR() with the addition that it also returns the * subject task's prior notification value (the notification value at the time * the function is called rather than at the time the function returns) in the * additional pulPreviousNotifyValue parameter. * * xTaskNotifyAndQueryFromISR() performs the same operation as * xTaskNotifyFromISR() with the addition that it also returns the subject * task's prior notification value (the notification value at the time the * function is called rather than at the time the function returns) in the * additional pulPreviousNotifyValue parameter. * * \defgroup xTaskNotifyAndQueryIndexedFromISR xTaskNotifyAndQueryIndexedFromISR * \ingroup TaskNotifications */ #define xTaskNotifyAndQueryIndexedFromISR( xTaskToNotify, uxIndexToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) \ xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) ) #define xTaskNotifyAndQueryFromISR( xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) \ xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) ) /** * task. h * @code{c} * BaseType_t xTaskNotifyWaitIndexed( UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ); * * BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ); * @endcode * * Waits for a direct to task notification to be pending at a given index within * an array of direct to task notifications. * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this * function to be available. * * Each task has a private array of "notification values" (or 'notifications'), * each of which is a 32-bit unsigned integer (uint32_t). The constant * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the * array, and (for backward compatibility) defaults to 1 if left undefined. * Prior to FreeRTOS V10.4.0 there was only one notification value per task. * * Events can be sent to a task using an intermediary object. Examples of such * objects are queues, semaphores, mutexes and event groups. Task notifications * are a method of sending an event directly to a task without the need for such * an intermediary object. * * A notification sent to a task can optionally perform an action, such as * update, overwrite or increment one of the task's notification values. In * that way task notifications can be used to send data to a task, or be used as * light weight and fast binary or counting semaphores. * * A notification sent to a task will remain pending until it is cleared by the * task calling xTaskNotifyWaitIndexed() or ulTaskNotifyTakeIndexed() (or their * un-indexed equivalents). If the task was already in the Blocked state to * wait for a notification when the notification arrives then the task will * automatically be removed from the Blocked state (unblocked) and the * notification cleared. * * A task can use xTaskNotifyWaitIndexed() to [optionally] block to wait for a * notification to be pending, or ulTaskNotifyTakeIndexed() to [optionally] block * to wait for a notification value to have a non-zero value. The task does * not consume any CPU time while it is in the Blocked state. * * **NOTE** Each notification within the array operates independently - a task * can only block on one notification within the array at a time and will not be * unblocked by a notification sent to any other array index. * * Backward compatibility information: * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and * all task notification API functions operated on that value. Replacing the * single notification value with an array of notification values necessitated a * new set of API functions that could address specific notifications within the * array. xTaskNotifyWait() is the original API function, and remains backward * compatible by always operating on the notification value at index 0 in the * array. Calling xTaskNotifyWait() is equivalent to calling * xTaskNotifyWaitIndexed() with the uxIndexToWaitOn parameter set to 0. * * @param uxIndexToWaitOn The index within the calling task's array of * notification values on which the calling task will wait for a notification to * be received. uxIndexToWaitOn must be less than * configTASK_NOTIFICATION_ARRAY_ENTRIES. xTaskNotifyWait() does * not have this parameter and always waits for notifications on index 0. * * @param ulBitsToClearOnEntry Bits that are set in ulBitsToClearOnEntry value * will be cleared in the calling task's notification value before the task * checks to see if any notifications are pending, and optionally blocks if no * notifications are pending. Setting ulBitsToClearOnEntry to ULONG_MAX (if * limits.h is included) or 0xffffffffUL (if limits.h is not included) will have * the effect of resetting the task's notification value to 0. Setting * ulBitsToClearOnEntry to 0 will leave the task's notification value unchanged. * * @param ulBitsToClearOnExit If a notification is pending or received before * the calling task exits the xTaskNotifyWait() function then the task's * notification value (see the xTaskNotify() API function) is passed out using * the pulNotificationValue parameter. Then any bits that are set in * ulBitsToClearOnExit will be cleared in the task's notification value (note * *pulNotificationValue is set before any bits are cleared). Setting * ulBitsToClearOnExit to ULONG_MAX (if limits.h is included) or 0xffffffffUL * (if limits.h is not included) will have the effect of resetting the task's * notification value to 0 before the function exits. Setting * ulBitsToClearOnExit to 0 will leave the task's notification value unchanged * when the function exits (in which case the value passed out in * pulNotificationValue will match the task's notification value). * * @param pulNotificationValue Used to pass the task's notification value out * of the function. Note the value passed out will not be effected by the * clearing of any bits caused by ulBitsToClearOnExit being non-zero. * * @param xTicksToWait The maximum amount of time that the task should wait in * the Blocked state for a notification to be received, should a notification * not already be pending when xTaskNotifyWait() was called. The task * will not consume any processing time while it is in the Blocked state. This * is specified in kernel ticks, the macro pdMS_TO_TICKS( value_in_ms ) can be * used to convert a time specified in milliseconds to a time specified in * ticks. * * @return If a notification was received (including notifications that were * already pending when xTaskNotifyWait was called) then pdPASS is * returned. Otherwise pdFAIL is returned. * * \defgroup xTaskNotifyWaitIndexed xTaskNotifyWaitIndexed * \ingroup TaskNotifications */ BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t * pulNotificationValue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; #define xTaskNotifyWait( ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ) \ xTaskGenericNotifyWait( tskDEFAULT_INDEX_TO_NOTIFY, ( ulBitsToClearOnEntry ), ( ulBitsToClearOnExit ), ( pulNotificationValue ), ( xTicksToWait ) ) #define xTaskNotifyWaitIndexed( uxIndexToWaitOn, ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ) \ xTaskGenericNotifyWait( ( uxIndexToWaitOn ), ( ulBitsToClearOnEntry ), ( ulBitsToClearOnExit ), ( pulNotificationValue ), ( xTicksToWait ) ) /** * task. h * @code{c} * BaseType_t xTaskNotifyGiveIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify ); * BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify ); * @endcode * * Sends a direct to task notification to a particular index in the target * task's notification array in a manner similar to giving a counting semaphore. * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for more details. * * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these * macros to be available. * * Each task has a private array of "notification values" (or 'notifications'), * each of which is a 32-bit unsigned integer (uint32_t). The constant * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the * array, and (for backward compatibility) defaults to 1 if left undefined. * Prior to FreeRTOS V10.4.0 there was only one notification value per task. * * Events can be sent to a task using an intermediary object. Examples of such * objects are queues, semaphores, mutexes and event groups. Task notifications * are a method of sending an event directly to a task without the need for such * an intermediary object. * * A notification sent to a task can optionally perform an action, such as * update, overwrite or increment one of the task's notification values. In * that way task notifications can be used to send data to a task, or be used as * light weight and fast binary or counting semaphores. * * xTaskNotifyGiveIndexed() is a helper macro intended for use when task * notifications are used as light weight and faster binary or counting * semaphore equivalents. Actual FreeRTOS semaphores are given using the * xSemaphoreGive() API function, the equivalent action that instead uses a task * notification is xTaskNotifyGiveIndexed(). * * When task notifications are being used as a binary or counting semaphore * equivalent then the task being notified should wait for the notification * using the ulTaskNotifyTakeIndexed() API function rather than the * xTaskNotifyWaitIndexed() API function. * * **NOTE** Each notification within the array operates independently - a task * can only block on one notification within the array at a time and will not be * unblocked by a notification sent to any other array index. * * Backward compatibility information: * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and * all task notification API functions operated on that value. Replacing the * single notification value with an array of notification values necessitated a * new set of API functions that could address specific notifications within the * array. xTaskNotifyGive() is the original API function, and remains backward * compatible by always operating on the notification value at index 0 in the * array. Calling xTaskNotifyGive() is equivalent to calling * xTaskNotifyGiveIndexed() with the uxIndexToNotify parameter set to 0. * * @param xTaskToNotify The handle of the task being notified. The handle to a * task can be returned from the xTaskCreate() API function used to create the * task, and the handle of the currently running task can be obtained by calling * xTaskGetCurrentTaskHandle(). * * @param uxIndexToNotify The index within the target task's array of * notification values to which the notification is to be sent. uxIndexToNotify * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. xTaskNotifyGive() * does not have this parameter and always sends notifications to index 0. * * @return xTaskNotifyGive() is a macro that calls xTaskNotify() with the * eAction parameter set to eIncrement - so pdPASS is always returned. * * \defgroup xTaskNotifyGiveIndexed xTaskNotifyGiveIndexed * \ingroup TaskNotifications */ #define xTaskNotifyGive( xTaskToNotify ) \ xTaskGenericNotify( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( 0 ), eIncrement, NULL ) #define xTaskNotifyGiveIndexed( xTaskToNotify, uxIndexToNotify ) \ xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( 0 ), eIncrement, NULL ) /** * task. h * @code{c} * void vTaskNotifyGiveIndexedFromISR( TaskHandle_t xTaskHandle, UBaseType_t uxIndexToNotify, BaseType_t *pxHigherPriorityTaskWoken ); * void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken ); * @endcode * * A version of xTaskNotifyGiveIndexed() that can be called from an interrupt * service routine (ISR). * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for more details. * * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro * to be available. * * Each task has a private array of "notification values" (or 'notifications'), * each of which is a 32-bit unsigned integer (uint32_t). The constant * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the * array, and (for backward compatibility) defaults to 1 if left undefined. * Prior to FreeRTOS V10.4.0 there was only one notification value per task. * * Events can be sent to a task using an intermediary object. Examples of such * objects are queues, semaphores, mutexes and event groups. Task notifications * are a method of sending an event directly to a task without the need for such * an intermediary object. * * A notification sent to a task can optionally perform an action, such as * update, overwrite or increment one of the task's notification values. In * that way task notifications can be used to send data to a task, or be used as * light weight and fast binary or counting semaphores. * * vTaskNotifyGiveIndexedFromISR() is intended for use when task notifications * are used as light weight and faster binary or counting semaphore equivalents. * Actual FreeRTOS semaphores are given from an ISR using the * xSemaphoreGiveFromISR() API function, the equivalent action that instead uses * a task notification is vTaskNotifyGiveIndexedFromISR(). * * When task notifications are being used as a binary or counting semaphore * equivalent then the task being notified should wait for the notification * using the ulTaskNotifyTakeIndexed() API function rather than the * xTaskNotifyWaitIndexed() API function. * * **NOTE** Each notification within the array operates independently - a task * can only block on one notification within the array at a time and will not be * unblocked by a notification sent to any other array index. * * Backward compatibility information: * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and * all task notification API functions operated on that value. Replacing the * single notification value with an array of notification values necessitated a * new set of API functions that could address specific notifications within the * array. xTaskNotifyFromISR() is the original API function, and remains * backward compatible by always operating on the notification value at index 0 * within the array. Calling xTaskNotifyGiveFromISR() is equivalent to calling * xTaskNotifyGiveIndexedFromISR() with the uxIndexToNotify parameter set to 0. * * @param xTaskToNotify The handle of the task being notified. The handle to a * task can be returned from the xTaskCreate() API function used to create the * task, and the handle of the currently running task can be obtained by calling * xTaskGetCurrentTaskHandle(). * * @param uxIndexToNotify The index within the target task's array of * notification values to which the notification is to be sent. uxIndexToNotify * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. * xTaskNotifyGiveFromISR() does not have this parameter and always sends * notifications to index 0. * * @param pxHigherPriorityTaskWoken vTaskNotifyGiveFromISR() will set * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the * task to which the notification was sent to leave the Blocked state, and the * unblocked task has a priority higher than the currently running task. If * vTaskNotifyGiveFromISR() sets this value to pdTRUE then a context switch * should be requested before the interrupt is exited. How a context switch is * requested from an ISR is dependent on the port - see the documentation page * for the port in use. * * \defgroup vTaskNotifyGiveIndexedFromISR vTaskNotifyGiveIndexedFromISR * \ingroup TaskNotifications */ void vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; #define vTaskNotifyGiveFromISR( xTaskToNotify, pxHigherPriorityTaskWoken ) \ vTaskGenericNotifyGiveFromISR( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( pxHigherPriorityTaskWoken ) ) #define vTaskNotifyGiveIndexedFromISR( xTaskToNotify, uxIndexToNotify, pxHigherPriorityTaskWoken ) \ vTaskGenericNotifyGiveFromISR( ( xTaskToNotify ), ( uxIndexToNotify ), ( pxHigherPriorityTaskWoken ) ) /** * task. h * @code{c} * uint32_t ulTaskNotifyTakeIndexed( UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t xTicksToWait ); * * uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ); * @endcode * * Waits for a direct to task notification on a particular index in the calling * task's notification array in a manner similar to taking a counting semaphore. * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this * function to be available. * * Each task has a private array of "notification values" (or 'notifications'), * each of which is a 32-bit unsigned integer (uint32_t). The constant * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the * array, and (for backward compatibility) defaults to 1 if left undefined. * Prior to FreeRTOS V10.4.0 there was only one notification value per task. * * Events can be sent to a task using an intermediary object. Examples of such * objects are queues, semaphores, mutexes and event groups. Task notifications * are a method of sending an event directly to a task without the need for such * an intermediary object. * * A notification sent to a task can optionally perform an action, such as * update, overwrite or increment one of the task's notification values. In * that way task notifications can be used to send data to a task, or be used as * light weight and fast binary or counting semaphores. * * ulTaskNotifyTakeIndexed() is intended for use when a task notification is * used as a faster and lighter weight binary or counting semaphore alternative. * Actual FreeRTOS semaphores are taken using the xSemaphoreTake() API function, * the equivalent action that instead uses a task notification is * ulTaskNotifyTakeIndexed(). * * When a task is using its notification value as a binary or counting semaphore * other tasks should send notifications to it using the xTaskNotifyGiveIndexed() * macro, or xTaskNotifyIndex() function with the eAction parameter set to * eIncrement. * * ulTaskNotifyTakeIndexed() can either clear the task's notification value at * the array index specified by the uxIndexToWaitOn parameter to zero on exit, * in which case the notification value acts like a binary semaphore, or * decrement the notification value on exit, in which case the notification * value acts like a counting semaphore. * * A task can use ulTaskNotifyTakeIndexed() to [optionally] block to wait for * a notification. The task does not consume any CPU time while it is in the * Blocked state. * * Where as xTaskNotifyWaitIndexed() will return when a notification is pending, * ulTaskNotifyTakeIndexed() will return when the task's notification value is * not zero. * * **NOTE** Each notification within the array operates independently - a task * can only block on one notification within the array at a time and will not be * unblocked by a notification sent to any other array index. * * Backward compatibility information: * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and * all task notification API functions operated on that value. Replacing the * single notification value with an array of notification values necessitated a * new set of API functions that could address specific notifications within the * array. ulTaskNotifyTake() is the original API function, and remains backward * compatible by always operating on the notification value at index 0 in the * array. Calling ulTaskNotifyTake() is equivalent to calling * ulTaskNotifyTakeIndexed() with the uxIndexToWaitOn parameter set to 0. * * @param uxIndexToWaitOn The index within the calling task's array of * notification values on which the calling task will wait for a notification to * be non-zero. uxIndexToWaitOn must be less than * configTASK_NOTIFICATION_ARRAY_ENTRIES. xTaskNotifyTake() does * not have this parameter and always waits for notifications on index 0. * * @param xClearCountOnExit if xClearCountOnExit is pdFALSE then the task's * notification value is decremented when the function exits. In this way the * notification value acts like a counting semaphore. If xClearCountOnExit is * not pdFALSE then the task's notification value is cleared to zero when the * function exits. In this way the notification value acts like a binary * semaphore. * * @param xTicksToWait The maximum amount of time that the task should wait in * the Blocked state for the task's notification value to be greater than zero, * should the count not already be greater than zero when * ulTaskNotifyTake() was called. The task will not consume any processing * time while it is in the Blocked state. This is specified in kernel ticks, * the macro pdMS_TO_TICKS( value_in_ms ) can be used to convert a time * specified in milliseconds to a time specified in ticks. * * @return The task's notification count before it is either cleared to zero or * decremented (see the xClearCountOnExit parameter). * * \defgroup ulTaskNotifyTakeIndexed ulTaskNotifyTakeIndexed * \ingroup TaskNotifications */ uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; #define ulTaskNotifyTake( xClearCountOnExit, xTicksToWait ) \ ulTaskGenericNotifyTake( ( tskDEFAULT_INDEX_TO_NOTIFY ), ( xClearCountOnExit ), ( xTicksToWait ) ) #define ulTaskNotifyTakeIndexed( uxIndexToWaitOn, xClearCountOnExit, xTicksToWait ) \ ulTaskGenericNotifyTake( ( uxIndexToWaitOn ), ( xClearCountOnExit ), ( xTicksToWait ) ) /** * task. h * @code{c} * BaseType_t xTaskNotifyStateClearIndexed( TaskHandle_t xTask, UBaseType_t uxIndexToCLear ); * * BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask ); * @endcode * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these * functions to be available. * * Each task has a private array of "notification values" (or 'notifications'), * each of which is a 32-bit unsigned integer (uint32_t). The constant * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the * array, and (for backward compatibility) defaults to 1 if left undefined. * Prior to FreeRTOS V10.4.0 there was only one notification value per task. * * If a notification is sent to an index within the array of notifications then * the notification at that index is said to be 'pending' until it is read or * explicitly cleared by the receiving task. xTaskNotifyStateClearIndexed() * is the function that clears a pending notification without reading the * notification value. The notification value at the same array index is not * altered. Set xTask to NULL to clear the notification state of the calling * task. * * Backward compatibility information: * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and * all task notification API functions operated on that value. Replacing the * single notification value with an array of notification values necessitated a * new set of API functions that could address specific notifications within the * array. xTaskNotifyStateClear() is the original API function, and remains * backward compatible by always operating on the notification value at index 0 * within the array. Calling xTaskNotifyStateClear() is equivalent to calling * xTaskNotifyStateClearIndexed() with the uxIndexToNotify parameter set to 0. * * @param xTask The handle of the RTOS task that will have a notification state * cleared. Set xTask to NULL to clear a notification state in the calling * task. To obtain a task's handle create the task using xTaskCreate() and * make use of the pxCreatedTask parameter, or create the task using * xTaskCreateStatic() and store the returned value, or use the task's name in * a call to xTaskGetHandle(). * * @param uxIndexToClear The index within the target task's array of * notification values to act upon. For example, setting uxIndexToClear to 1 * will clear the state of the notification at index 1 within the array. * uxIndexToClear must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. * ulTaskNotifyStateClear() does not have this parameter and always acts on the * notification at index 0. * * @return pdTRUE if the task's notification state was set to * eNotWaitingNotification, otherwise pdFALSE. * * \defgroup xTaskNotifyStateClearIndexed xTaskNotifyStateClearIndexed * \ingroup TaskNotifications */ BaseType_t xTaskGenericNotifyStateClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear ) PRIVILEGED_FUNCTION; #define xTaskNotifyStateClear( xTask ) \ xTaskGenericNotifyStateClear( ( xTask ), ( tskDEFAULT_INDEX_TO_NOTIFY ) ) #define xTaskNotifyStateClearIndexed( xTask, uxIndexToClear ) \ xTaskGenericNotifyStateClear( ( xTask ), ( uxIndexToClear ) ) /** * task. h * @code{c} * uint32_t ulTaskNotifyValueClearIndexed( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear ); * * uint32_t ulTaskNotifyValueClear( TaskHandle_t xTask, uint32_t ulBitsToClear ); * @endcode * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these * functions to be available. * * Each task has a private array of "notification values" (or 'notifications'), * each of which is a 32-bit unsigned integer (uint32_t). The constant * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the * array, and (for backward compatibility) defaults to 1 if left undefined. * Prior to FreeRTOS V10.4.0 there was only one notification value per task. * * ulTaskNotifyValueClearIndexed() clears the bits specified by the * ulBitsToClear bit mask in the notification value at array index uxIndexToClear * of the task referenced by xTask. * * Backward compatibility information: * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and * all task notification API functions operated on that value. Replacing the * single notification value with an array of notification values necessitated a * new set of API functions that could address specific notifications within the * array. ulTaskNotifyValueClear() is the original API function, and remains * backward compatible by always operating on the notification value at index 0 * within the array. Calling ulTaskNotifyValueClear() is equivalent to calling * ulTaskNotifyValueClearIndexed() with the uxIndexToClear parameter set to 0. * * @param xTask The handle of the RTOS task that will have bits in one of its * notification values cleared. Set xTask to NULL to clear bits in a * notification value of the calling task. To obtain a task's handle create the * task using xTaskCreate() and make use of the pxCreatedTask parameter, or * create the task using xTaskCreateStatic() and store the returned value, or * use the task's name in a call to xTaskGetHandle(). * * @param uxIndexToClear The index within the target task's array of * notification values in which to clear the bits. uxIndexToClear * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. * ulTaskNotifyValueClear() does not have this parameter and always clears bits * in the notification value at index 0. * * @param ulBitsToClear Bit mask of the bits to clear in the notification value of * xTask. Set a bit to 1 to clear the corresponding bits in the task's notification * value. Set ulBitsToClear to 0xffffffff (UINT_MAX on 32-bit architectures) to clear * the notification value to 0. Set ulBitsToClear to 0 to query the task's * notification value without clearing any bits. * * * @return The value of the target task's notification value before the bits * specified by ulBitsToClear were cleared. * \defgroup ulTaskNotifyValueClear ulTaskNotifyValueClear * \ingroup TaskNotifications */ uint32_t ulTaskGenericNotifyValueClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION; #define ulTaskNotifyValueClear( xTask, ulBitsToClear ) \ ulTaskGenericNotifyValueClear( ( xTask ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulBitsToClear ) ) #define ulTaskNotifyValueClearIndexed( xTask, uxIndexToClear, ulBitsToClear ) \ ulTaskGenericNotifyValueClear( ( xTask ), ( uxIndexToClear ), ( ulBitsToClear ) ) /** * task.h * @code{c} * void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ); * @endcode * * Capture the current time for future use with xTaskCheckForTimeOut(). * * @param pxTimeOut Pointer to a timeout object into which the current time * is to be captured. The captured time includes the tick count and the number * of times the tick count has overflowed since the system first booted. * \defgroup vTaskSetTimeOutState vTaskSetTimeOutState * \ingroup TaskCtrl */ void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; /** * task.h * @code{c} * BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ); * @endcode * * Determines if pxTicksToWait ticks has passed since a time was captured * using a call to vTaskSetTimeOutState(). The captured time includes the tick * count and the number of times the tick count has overflowed. * * @param pxTimeOut The time status as captured previously using * vTaskSetTimeOutState. If the timeout has not yet occurred, it is updated * to reflect the current time status. * @param pxTicksToWait The number of ticks to check for timeout i.e. if * pxTicksToWait ticks have passed since pxTimeOut was last updated (either by * vTaskSetTimeOutState() or xTaskCheckForTimeOut()), the timeout has occurred. * If the timeout has not occurred, pxTicksToWait is updated to reflect the * number of remaining ticks. * * @return If timeout has occurred, pdTRUE is returned. Otherwise pdFALSE is * returned and pxTicksToWait is updated to reflect the number of remaining * ticks. * * @see https://www.FreeRTOS.org/xTaskCheckForTimeOut.html * * Example Usage: * @code{c} * // Driver library function used to receive uxWantedBytes from an Rx buffer * // that is filled by a UART interrupt. If there are not enough bytes in the * // Rx buffer then the task enters the Blocked state until it is notified that * // more data has been placed into the buffer. If there is still not enough * // data then the task re-enters the Blocked state, and xTaskCheckForTimeOut() * // is used to re-calculate the Block time to ensure the total amount of time * // spent in the Blocked state does not exceed MAX_TIME_TO_WAIT. This * // continues until either the buffer contains at least uxWantedBytes bytes, * // or the total amount of time spent in the Blocked state reaches * // MAX_TIME_TO_WAIT - at which point the task reads however many bytes are * // available up to a maximum of uxWantedBytes. * * size_t xUART_Receive( uint8_t *pucBuffer, size_t uxWantedBytes ) * { * size_t uxReceived = 0; * TickType_t xTicksToWait = MAX_TIME_TO_WAIT; * TimeOut_t xTimeOut; * * // Initialize xTimeOut. This records the time at which this function * // was entered. * vTaskSetTimeOutState( &xTimeOut ); * * // Loop until the buffer contains the wanted number of bytes, or a * // timeout occurs. * while( UART_bytes_in_rx_buffer( pxUARTInstance ) < uxWantedBytes ) * { * // The buffer didn't contain enough data so this task is going to * // enter the Blocked state. Adjusting xTicksToWait to account for * // any time that has been spent in the Blocked state within this * // function so far to ensure the total amount of time spent in the * // Blocked state does not exceed MAX_TIME_TO_WAIT. * if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) != pdFALSE ) * { * //Timed out before the wanted number of bytes were available, * // exit the loop. * break; * } * * // Wait for a maximum of xTicksToWait ticks to be notified that the * // receive interrupt has placed more data into the buffer. * ulTaskNotifyTake( pdTRUE, xTicksToWait ); * } * * // Attempt to read uxWantedBytes from the receive buffer into pucBuffer. * // The actual number of bytes read (which might be less than * // uxWantedBytes) is returned. * uxReceived = UART_read_from_receive_buffer( pxUARTInstance, * pucBuffer, * uxWantedBytes ); * * return uxReceived; * } * @endcode * \defgroup xTaskCheckForTimeOut xTaskCheckForTimeOut * \ingroup TaskCtrl */ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) PRIVILEGED_FUNCTION; /** * task.h * @code{c} * BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ); * @endcode * * This function corrects the tick count value after the application code has held * interrupts disabled for an extended period resulting in tick interrupts having * been missed. * * This function is similar to vTaskStepTick(), however, unlike * vTaskStepTick(), xTaskCatchUpTicks() may move the tick count forward past a * time at which a task should be removed from the blocked state. That means * tasks may have to be removed from the blocked state as the tick count is * moved. * * @param xTicksToCatchUp The number of tick interrupts that have been missed due to * interrupts being disabled. Its value is not computed automatically, so must be * computed by the application writer. * * @return pdTRUE if moving the tick count forward resulted in a task leaving the * blocked state and a context switch being performed. Otherwise pdFALSE. * * \defgroup xTaskCatchUpTicks xTaskCatchUpTicks * \ingroup TaskCtrl */ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) PRIVILEGED_FUNCTION; /*----------------------------------------------------------- * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES *----------------------------------------------------------*/ /* * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. * * Called from the real time kernel tick (either preemptive or cooperative), * this increments the tick count and checks if any tasks that are blocked * for a finite period required removing from a blocked list and placing on * a ready list. If a non-zero value is returned then a context switch is * required because either: * + A task was removed from a blocked list because its timeout had expired, * or * + Time slicing is in use and there is a task of equal priority to the * currently running task. */ BaseType_t xTaskIncrementTick( void ) PRIVILEGED_FUNCTION; /* * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. * * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. * * Removes the calling task from the ready list and places it both * on the list of tasks waiting for a particular event, and the * list of delayed tasks. The task will be removed from both lists * and replaced on the ready list should either the event occur (and * there be no higher priority tasks waiting on the same event) or * the delay period expires. * * The 'unordered' version replaces the event list item value with the * xItemValue value, and inserts the list item at the end of the list. * * The 'ordered' version uses the existing event list item value (which is the * owning task's priority) to insert the list item into the event list in task * priority order. * * @param pxEventList The list containing tasks that are blocked waiting * for the event to occur. * * @param xItemValue The item value to use for the event list item when the * event list is not ordered by task priority. * * @param xTicksToWait The maximum amount of time that the task should wait * for the event to occur. This is specified in kernel ticks, the constant * portTICK_PERIOD_MS can be used to convert kernel ticks into a real time * period. */ void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /* * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. * * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. * * This function performs nearly the same function as vTaskPlaceOnEventList(). * The difference being that this function does not permit tasks to block * indefinitely, whereas vTaskPlaceOnEventList() does. * */ void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION; /* * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. * * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. * * Removes a task from both the specified event list and the list of blocked * tasks, and places it on a ready queue. * * xTaskRemoveFromEventList()/vTaskRemoveFromUnorderedEventList() will be called * if either an event occurs to unblock a task, or the block timeout period * expires. * * xTaskRemoveFromEventList() is used when the event list is in task priority * order. It removes the list item from the head of the event list as that will * have the highest priority owning task of all the tasks on the event list. * vTaskRemoveFromUnorderedEventList() is used when the event list is not * ordered and the event list items hold something other than the owning tasks * priority. In this case the event list item value is updated to the value * passed in the xItemValue parameter. * * @return pdTRUE if the task being removed has a higher priority than the task * making the call, otherwise pdFALSE. */ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION; void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) PRIVILEGED_FUNCTION; /* * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. * * Sets the pointer to the current TCB to the TCB of the highest priority task * that is ready to run. */ portDONT_DISCARD void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION; /* * THESE FUNCTIONS MUST NOT BE USED FROM APPLICATION CODE. THEY ARE USED BY * THE EVENT BITS MODULE. */ TickType_t uxTaskResetEventItemValue( void ) PRIVILEGED_FUNCTION; /* * Return the handle of the calling task. */ TaskHandle_t xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; /* * Shortcut used by the queue implementation to prevent unnecessary call to * taskYIELD(); */ void vTaskMissedYield( void ) PRIVILEGED_FUNCTION; /* * Returns the scheduler state as taskSCHEDULER_RUNNING, * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED. */ BaseType_t xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION; /* * Raises the priority of the mutex holder to that of the calling task should * the mutex holder have a priority less than the calling task. */ BaseType_t xTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; /* * Set the priority of a task back to its proper priority in the case that it * inherited a higher priority while it was holding a semaphore. */ BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; /* * If a higher priority task attempting to obtain a mutex caused a lower * priority task to inherit the higher priority task's priority - but the higher * priority task then timed out without obtaining the mutex, then the lower * priority task will disinherit the priority again - but only down as far as * the highest priority task that is still waiting for the mutex (if there were * more than one task waiting for the mutex). */ void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder, UBaseType_t uxHighestPriorityWaitingTask ) PRIVILEGED_FUNCTION; /* * Get the uxTaskNumber assigned to the task referenced by the xTask parameter. */ UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /* * Set the uxTaskNumber of the task referenced by the xTask parameter to * uxHandle. */ void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle ) PRIVILEGED_FUNCTION; /* * Only available when configUSE_TICKLESS_IDLE is set to 1. * If tickless mode is being used, or a low power mode is implemented, then * the tick interrupt will not execute during idle periods. When this is the * case, the tick count value maintained by the scheduler needs to be kept up * to date with the actual execution time by being skipped forward by a time * equal to the idle period. */ void vTaskStepTick( TickType_t xTicksToJump ) PRIVILEGED_FUNCTION; /* * Only available when configUSE_TICKLESS_IDLE is set to 1. * Provided for use within portSUPPRESS_TICKS_AND_SLEEP() to allow the port * specific sleep function to determine if it is ok to proceed with the sleep, * and if it is ok to proceed, if it is ok to sleep indefinitely. * * This function is necessary because portSUPPRESS_TICKS_AND_SLEEP() is only * called with the scheduler suspended, not from within a critical section. It * is therefore possible for an interrupt to request a context switch between * portSUPPRESS_TICKS_AND_SLEEP() and the low power mode actually being * entered. eTaskConfirmSleepModeStatus() should be called from a short * critical section between the timer being stopped and the sleep mode being * entered to ensure it is ok to proceed into the sleep mode. */ eSleepModeStatus eTaskConfirmSleepModeStatus( void ) PRIVILEGED_FUNCTION; /* * For internal use only. Increment the mutex held count when a mutex is * taken and return the handle of the task that has taken the mutex. */ TaskHandle_t pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION; /* * For internal use only. Same as vTaskSetTimeOutState(), but without a critical * section. */ void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* INC_TASK_H */ ================================================ FILE: FreeRTOS-comparison/include/timers.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef TIMERS_H #define TIMERS_H #ifndef INC_FREERTOS_H #error "include FreeRTOS.h must appear in source files before include timers.h" #endif /*lint -save -e537 This headers are only multiply included if the application code * happens to also be including task.h. */ #include "task.h" /*lint -restore */ /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ /*----------------------------------------------------------- * MACROS AND DEFINITIONS *----------------------------------------------------------*/ /* IDs for commands that can be sent/received on the timer queue. These are to * be used solely through the macros that make up the public software timer API, * as defined below. The commands that are sent from interrupts must use the * highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task * or interrupt version of the queue send function should be used. */ #define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 ) #define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 ) #define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 ) #define tmrCOMMAND_START ( ( BaseType_t ) 1 ) #define tmrCOMMAND_RESET ( ( BaseType_t ) 2 ) #define tmrCOMMAND_STOP ( ( BaseType_t ) 3 ) #define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 ) #define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 ) #define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 ) #define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 ) #define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 ) #define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 ) #define tmrCOMMAND_CHANGE_PERIOD_FROM_ISR ( ( BaseType_t ) 9 ) /** * Type by which software timers are referenced. For example, a call to * xTimerCreate() returns an TimerHandle_t variable that can then be used to * reference the subject timer in calls to other software timer API functions * (for example, xTimerStart(), xTimerReset(), etc.). */ struct tmrTimerControl; /* The old naming convention is used to prevent breaking kernel aware debuggers. */ typedef struct tmrTimerControl * TimerHandle_t; /* * Defines the prototype to which timer callback functions must conform. */ typedef void (* TimerCallbackFunction_t)( TimerHandle_t xTimer ); /* * Defines the prototype to which functions used with the * xTimerPendFunctionCallFromISR() function must conform. */ typedef void (* PendedFunction_t)( void *, uint32_t ); /** * TimerHandle_t xTimerCreate( const char * const pcTimerName, * TickType_t xTimerPeriodInTicks, * BaseType_t xAutoReload, * void * pvTimerID, * TimerCallbackFunction_t pxCallbackFunction ); * * Creates a new software timer instance, and returns a handle by which the * created software timer can be referenced. * * Internally, within the FreeRTOS implementation, software timers use a block * of memory, in which the timer data structure is stored. If a software timer * is created using xTimerCreate() then the required memory is automatically * dynamically allocated inside the xTimerCreate() function. (see * https://www.FreeRTOS.org/a00111.html). If a software timer is created using * xTimerCreateStatic() then the application writer must provide the memory that * will get used by the software timer. xTimerCreateStatic() therefore allows a * software timer to be created without using any dynamic memory allocation. * * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and * xTimerChangePeriodFromISR() API functions can all be used to transition a * timer into the active state. * * @param pcTimerName A text name that is assigned to the timer. This is done * purely to assist debugging. The kernel itself only ever references a timer * by its handle, and never by its name. * * @param xTimerPeriodInTicks The timer period. The time is defined in tick * periods so the constant portTICK_PERIOD_MS can be used to convert a time that * has been specified in milliseconds. For example, if the timer must expire * after 100 ticks, then xTimerPeriodInTicks should be set to 100. * Alternatively, if the timer must expire after 500ms, then xPeriod can be set * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or * equal to 1000. Time timer period must be greater than 0. * * @param xAutoReload If xAutoReload is set to pdTRUE then the timer will * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. * If xAutoReload is set to pdFALSE then the timer will be a one-shot timer and * enter the dormant state after it expires. * * @param pvTimerID An identifier that is assigned to the timer being created. * Typically this would be used in the timer callback function to identify which * timer expired when the same callback function is assigned to more than one * timer. * * @param pxCallbackFunction The function to call when the timer expires. * Callback functions must have the prototype defined by TimerCallbackFunction_t, * which is "void vCallbackFunction( TimerHandle_t xTimer );". * * @return If the timer is successfully created then a handle to the newly * created timer is returned. If the timer cannot be created because there is * insufficient FreeRTOS heap remaining to allocate the timer * structures then NULL is returned. * * Example usage: * @verbatim * #define NUM_TIMERS 5 * * // An array to hold handles to the created timers. * TimerHandle_t xTimers[ NUM_TIMERS ]; * * // An array to hold a count of the number of times each timer expires. * int32_t lExpireCounters[ NUM_TIMERS ] = { 0 }; * * // Define a callback function that will be used by multiple timer instances. * // The callback function does nothing but count the number of times the * // associated timer expires, and stop the timer once the timer has expired * // 10 times. * void vTimerCallback( TimerHandle_t pxTimer ) * { * int32_t lArrayIndex; * const int32_t xMaxExpiryCountBeforeStopping = 10; * * // Optionally do something if the pxTimer parameter is NULL. * configASSERT( pxTimer ); * * // Which timer expired? * lArrayIndex = ( int32_t ) pvTimerGetTimerID( pxTimer ); * * // Increment the number of times that pxTimer has expired. * lExpireCounters[ lArrayIndex ] += 1; * * // If the timer has expired 10 times then stop it from running. * if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping ) * { * // Do not use a block time if calling a timer API function from a * // timer callback function, as doing so could cause a deadlock! * xTimerStop( pxTimer, 0 ); * } * } * * void main( void ) * { * int32_t x; * * // Create then start some timers. Starting the timers before the scheduler * // has been started means the timers will start running immediately that * // the scheduler starts. * for( x = 0; x < NUM_TIMERS; x++ ) * { * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel. * ( 100 * ( x + 1 ) ), // The timer period in ticks. * pdTRUE, // The timers will auto-reload themselves when they expire. * ( void * ) x, // Assign each timer a unique id equal to its array index. * vTimerCallback // Each timer calls the same callback when it expires. * ); * * if( xTimers[ x ] == NULL ) * { * // The timer was not created. * } * else * { * // Start the timer. No block time is specified, and even if one was * // it would be ignored because the scheduler has not yet been * // started. * if( xTimerStart( xTimers[ x ], 0 ) != pdPASS ) * { * // The timer could not be set into the Active state. * } * } * } * * // ... * // Create tasks here. * // ... * * // Starting the scheduler will start the timers running as they have already * // been set into the active state. * vTaskStartScheduler(); * * // Should not reach here. * for( ;; ); * } * @endverbatim */ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const TickType_t xTimerPeriodInTicks, const BaseType_t xAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; #endif /** * TimerHandle_t xTimerCreateStatic(const char * const pcTimerName, * TickType_t xTimerPeriodInTicks, * BaseType_t xAutoReload, * void * pvTimerID, * TimerCallbackFunction_t pxCallbackFunction, * StaticTimer_t *pxTimerBuffer ); * * Creates a new software timer instance, and returns a handle by which the * created software timer can be referenced. * * Internally, within the FreeRTOS implementation, software timers use a block * of memory, in which the timer data structure is stored. If a software timer * is created using xTimerCreate() then the required memory is automatically * dynamically allocated inside the xTimerCreate() function. (see * https://www.FreeRTOS.org/a00111.html). If a software timer is created using * xTimerCreateStatic() then the application writer must provide the memory that * will get used by the software timer. xTimerCreateStatic() therefore allows a * software timer to be created without using any dynamic memory allocation. * * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and * xTimerChangePeriodFromISR() API functions can all be used to transition a * timer into the active state. * * @param pcTimerName A text name that is assigned to the timer. This is done * purely to assist debugging. The kernel itself only ever references a timer * by its handle, and never by its name. * * @param xTimerPeriodInTicks The timer period. The time is defined in tick * periods so the constant portTICK_PERIOD_MS can be used to convert a time that * has been specified in milliseconds. For example, if the timer must expire * after 100 ticks, then xTimerPeriodInTicks should be set to 100. * Alternatively, if the timer must expire after 500ms, then xPeriod can be set * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or * equal to 1000. The timer period must be greater than 0. * * @param xAutoReload If xAutoReload is set to pdTRUE then the timer will * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. * If xAutoReload is set to pdFALSE then the timer will be a one-shot timer and * enter the dormant state after it expires. * * @param pvTimerID An identifier that is assigned to the timer being created. * Typically this would be used in the timer callback function to identify which * timer expired when the same callback function is assigned to more than one * timer. * * @param pxCallbackFunction The function to call when the timer expires. * Callback functions must have the prototype defined by TimerCallbackFunction_t, * which is "void vCallbackFunction( TimerHandle_t xTimer );". * * @param pxTimerBuffer Must point to a variable of type StaticTimer_t, which * will be then be used to hold the software timer's data structures, removing * the need for the memory to be allocated dynamically. * * @return If the timer is created then a handle to the created timer is * returned. If pxTimerBuffer was NULL then NULL is returned. * * Example usage: * @verbatim * * // The buffer used to hold the software timer's data structure. * static StaticTimer_t xTimerBuffer; * * // A variable that will be incremented by the software timer's callback * // function. * UBaseType_t uxVariableToIncrement = 0; * * // A software timer callback function that increments a variable passed to * // it when the software timer was created. After the 5th increment the * // callback function stops the software timer. * static void prvTimerCallback( TimerHandle_t xExpiredTimer ) * { * UBaseType_t *puxVariableToIncrement; * BaseType_t xReturned; * * // Obtain the address of the variable to increment from the timer ID. * puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer ); * * // Increment the variable to show the timer callback has executed. * ( *puxVariableToIncrement )++; * * // If this callback has executed the required number of times, stop the * // timer. * if( *puxVariableToIncrement == 5 ) * { * // This is called from a timer callback so must not block. * xTimerStop( xExpiredTimer, staticDONT_BLOCK ); * } * } * * * void main( void ) * { * // Create the software time. xTimerCreateStatic() has an extra parameter * // than the normal xTimerCreate() API function. The parameter is a pointer * // to the StaticTimer_t structure that will hold the software timer * // structure. If the parameter is passed as NULL then the structure will be * // allocated dynamically, just as if xTimerCreate() had been called. * xTimer = xTimerCreateStatic( "T1", // Text name for the task. Helps debugging only. Not used by FreeRTOS. * xTimerPeriod, // The period of the timer in ticks. * pdTRUE, // This is an auto-reload timer. * ( void * ) &uxVariableToIncrement, // A variable incremented by the software timer's callback function * prvTimerCallback, // The function to execute when the timer expires. * &xTimerBuffer ); // The buffer that will hold the software timer structure. * * // The scheduler has not started yet so a block time is not used. * xReturned = xTimerStart( xTimer, 0 ); * * // ... * // Create tasks here. * // ... * * // Starting the scheduler will start the timers running as they have already * // been set into the active state. * vTaskStartScheduler(); * * // Should not reach here. * for( ;; ); * } * @endverbatim */ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const TickType_t xTimerPeriodInTicks, const BaseType_t xAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t * pxTimerBuffer ) PRIVILEGED_FUNCTION; #endif /* configSUPPORT_STATIC_ALLOCATION */ /** * void *pvTimerGetTimerID( TimerHandle_t xTimer ); * * Returns the ID assigned to the timer. * * IDs are assigned to timers using the pvTimerID parameter of the call to * xTimerCreated() that was used to create the timer, and by calling the * vTimerSetTimerID() API function. * * If the same callback function is assigned to multiple timers then the timer * ID can be used as time specific (timer local) storage. * * @param xTimer The timer being queried. * * @return The ID assigned to the timer being queried. * * Example usage: * * See the xTimerCreate() API function example usage scenario. */ void * pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /** * void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ); * * Sets the ID assigned to the timer. * * IDs are assigned to timers using the pvTimerID parameter of the call to * xTimerCreated() that was used to create the timer. * * If the same callback function is assigned to multiple timers then the timer * ID can be used as time specific (timer local) storage. * * @param xTimer The timer being updated. * * @param pvNewID The ID to assign to the timer. * * Example usage: * * See the xTimerCreate() API function example usage scenario. */ void vTimerSetTimerID( TimerHandle_t xTimer, void * pvNewID ) PRIVILEGED_FUNCTION; /** * BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ); * * Queries a timer to see if it is active or dormant. * * A timer will be dormant if: * 1) It has been created but not started, or * 2) It is an expired one-shot timer that has not been restarted. * * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the * active state. * * @param xTimer The timer being queried. * * @return pdFALSE will be returned if the timer is dormant. A value other than * pdFALSE will be returned if the timer is active. * * Example usage: * @verbatim * // This function assumes xTimer has already been created. * void vAFunction( TimerHandle_t xTimer ) * { * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" * { * // xTimer is active, do something. * } * else * { * // xTimer is not active, do something else. * } * } * @endverbatim */ BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /** * TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); * * Simply returns the handle of the timer service/daemon task. It it not valid * to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started. */ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION; /** * BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait ); * * Timer functionality is provided by a timer service/daemon task. Many of the * public FreeRTOS timer API functions send commands to the timer service task * through a queue called the timer command queue. The timer command queue is * private to the kernel itself and is not directly accessible to application * code. The length of the timer command queue is set by the * configTIMER_QUEUE_LENGTH configuration constant. * * xTimerStart() starts a timer that was previously created using the * xTimerCreate() API function. If the timer had already been started and was * already in the active state, then xTimerStart() has equivalent functionality * to the xTimerReset() API function. * * Starting a timer ensures the timer is in the active state. If the timer * is not stopped, deleted, or reset in the mean time, the callback function * associated with the timer will get called 'n' ticks after xTimerStart() was * called, where 'n' is the timers defined period. * * It is valid to call xTimerStart() before the scheduler has been started, but * when this is done the timer will not actually start until the scheduler is * started, and the timers expiry time will be relative to when the scheduler is * started, not relative to when xTimerStart() was called. * * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart() * to be available. * * @param xTimer The handle of the timer being started/restarted. * * @param xTicksToWait Specifies the time, in ticks, that the calling task should * be held in the Blocked state to wait for the start command to be successfully * sent to the timer command queue, should the queue already be full when * xTimerStart() was called. xTicksToWait is ignored if xTimerStart() is called * before the scheduler is started. * * @return pdFAIL will be returned if the start command could not be sent to * the timer command queue even after xTicksToWait ticks had passed. pdPASS will * be returned if the command was successfully sent to the timer command queue. * When the command is actually processed will depend on the priority of the * timer service/daemon task relative to other tasks in the system, although the * timers expiry time is relative to when xTimerStart() is actually called. The * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY * configuration constant. * * Example usage: * * See the xTimerCreate() API function example usage scenario. * */ #define xTimerStart( xTimer, xTicksToWait ) \ xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) /** * BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait ); * * Timer functionality is provided by a timer service/daemon task. Many of the * public FreeRTOS timer API functions send commands to the timer service task * through a queue called the timer command queue. The timer command queue is * private to the kernel itself and is not directly accessible to application * code. The length of the timer command queue is set by the * configTIMER_QUEUE_LENGTH configuration constant. * * xTimerStop() stops a timer that was previously started using either of the * The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), * xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions. * * Stopping a timer ensures the timer is not in the active state. * * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop() * to be available. * * @param xTimer The handle of the timer being stopped. * * @param xTicksToWait Specifies the time, in ticks, that the calling task should * be held in the Blocked state to wait for the stop command to be successfully * sent to the timer command queue, should the queue already be full when * xTimerStop() was called. xTicksToWait is ignored if xTimerStop() is called * before the scheduler is started. * * @return pdFAIL will be returned if the stop command could not be sent to * the timer command queue even after xTicksToWait ticks had passed. pdPASS will * be returned if the command was successfully sent to the timer command queue. * When the command is actually processed will depend on the priority of the * timer service/daemon task relative to other tasks in the system. The timer * service/daemon task priority is set by the configTIMER_TASK_PRIORITY * configuration constant. * * Example usage: * * See the xTimerCreate() API function example usage scenario. * */ #define xTimerStop( xTimer, xTicksToWait ) \ xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) ) /** * BaseType_t xTimerChangePeriod( TimerHandle_t xTimer, * TickType_t xNewPeriod, * TickType_t xTicksToWait ); * * Timer functionality is provided by a timer service/daemon task. Many of the * public FreeRTOS timer API functions send commands to the timer service task * through a queue called the timer command queue. The timer command queue is * private to the kernel itself and is not directly accessible to application * code. The length of the timer command queue is set by the * configTIMER_QUEUE_LENGTH configuration constant. * * xTimerChangePeriod() changes the period of a timer that was previously * created using the xTimerCreate() API function. * * xTimerChangePeriod() can be called to change the period of an active or * dormant state timer. * * The configUSE_TIMERS configuration constant must be set to 1 for * xTimerChangePeriod() to be available. * * @param xTimer The handle of the timer that is having its period changed. * * @param xNewPeriod The new period for xTimer. Timer periods are specified in * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time * that has been specified in milliseconds. For example, if the timer must * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, * if the timer must expire after 500ms, then xNewPeriod can be set to * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than * or equal to 1000. * * @param xTicksToWait Specifies the time, in ticks, that the calling task should * be held in the Blocked state to wait for the change period command to be * successfully sent to the timer command queue, should the queue already be * full when xTimerChangePeriod() was called. xTicksToWait is ignored if * xTimerChangePeriod() is called before the scheduler is started. * * @return pdFAIL will be returned if the change period command could not be * sent to the timer command queue even after xTicksToWait ticks had passed. * pdPASS will be returned if the command was successfully sent to the timer * command queue. When the command is actually processed will depend on the * priority of the timer service/daemon task relative to other tasks in the * system. The timer service/daemon task priority is set by the * configTIMER_TASK_PRIORITY configuration constant. * * Example usage: * @verbatim * // This function assumes xTimer has already been created. If the timer * // referenced by xTimer is already active when it is called, then the timer * // is deleted. If the timer referenced by xTimer is not active when it is * // called, then the period of the timer is set to 500ms and the timer is * // started. * void vAFunction( TimerHandle_t xTimer ) * { * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" * { * // xTimer is already active - delete it. * xTimerDelete( xTimer ); * } * else * { * // xTimer is not active, change its period to 500ms. This will also * // cause the timer to start. Block for a maximum of 100 ticks if the * // change period command cannot immediately be sent to the timer * // command queue. * if( xTimerChangePeriod( xTimer, 500 / portTICK_PERIOD_MS, 100 ) == pdPASS ) * { * // The command was successfully sent. * } * else * { * // The command could not be sent, even after waiting for 100 ticks * // to pass. Take appropriate action here. * } * } * } * @endverbatim */ #define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) \ xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) ) /** * BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait ); * * Timer functionality is provided by a timer service/daemon task. Many of the * public FreeRTOS timer API functions send commands to the timer service task * through a queue called the timer command queue. The timer command queue is * private to the kernel itself and is not directly accessible to application * code. The length of the timer command queue is set by the * configTIMER_QUEUE_LENGTH configuration constant. * * xTimerDelete() deletes a timer that was previously created using the * xTimerCreate() API function. * * The configUSE_TIMERS configuration constant must be set to 1 for * xTimerDelete() to be available. * * @param xTimer The handle of the timer being deleted. * * @param xTicksToWait Specifies the time, in ticks, that the calling task should * be held in the Blocked state to wait for the delete command to be * successfully sent to the timer command queue, should the queue already be * full when xTimerDelete() was called. xTicksToWait is ignored if xTimerDelete() * is called before the scheduler is started. * * @return pdFAIL will be returned if the delete command could not be sent to * the timer command queue even after xTicksToWait ticks had passed. pdPASS will * be returned if the command was successfully sent to the timer command queue. * When the command is actually processed will depend on the priority of the * timer service/daemon task relative to other tasks in the system. The timer * service/daemon task priority is set by the configTIMER_TASK_PRIORITY * configuration constant. * * Example usage: * * See the xTimerChangePeriod() API function example usage scenario. */ #define xTimerDelete( xTimer, xTicksToWait ) \ xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) ) /** * BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait ); * * Timer functionality is provided by a timer service/daemon task. Many of the * public FreeRTOS timer API functions send commands to the timer service task * through a queue called the timer command queue. The timer command queue is * private to the kernel itself and is not directly accessible to application * code. The length of the timer command queue is set by the * configTIMER_QUEUE_LENGTH configuration constant. * * xTimerReset() re-starts a timer that was previously created using the * xTimerCreate() API function. If the timer had already been started and was * already in the active state, then xTimerReset() will cause the timer to * re-evaluate its expiry time so that it is relative to when xTimerReset() was * called. If the timer was in the dormant state then xTimerReset() has * equivalent functionality to the xTimerStart() API function. * * Resetting a timer ensures the timer is in the active state. If the timer * is not stopped, deleted, or reset in the mean time, the callback function * associated with the timer will get called 'n' ticks after xTimerReset() was * called, where 'n' is the timers defined period. * * It is valid to call xTimerReset() before the scheduler has been started, but * when this is done the timer will not actually start until the scheduler is * started, and the timers expiry time will be relative to when the scheduler is * started, not relative to when xTimerReset() was called. * * The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset() * to be available. * * @param xTimer The handle of the timer being reset/started/restarted. * * @param xTicksToWait Specifies the time, in ticks, that the calling task should * be held in the Blocked state to wait for the reset command to be successfully * sent to the timer command queue, should the queue already be full when * xTimerReset() was called. xTicksToWait is ignored if xTimerReset() is called * before the scheduler is started. * * @return pdFAIL will be returned if the reset command could not be sent to * the timer command queue even after xTicksToWait ticks had passed. pdPASS will * be returned if the command was successfully sent to the timer command queue. * When the command is actually processed will depend on the priority of the * timer service/daemon task relative to other tasks in the system, although the * timers expiry time is relative to when xTimerStart() is actually called. The * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY * configuration constant. * * Example usage: * @verbatim * // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass * // without a key being pressed, then the LCD back-light is switched off. In * // this case, the timer is a one-shot timer. * * TimerHandle_t xBacklightTimer = NULL; * * // The callback function assigned to the one-shot timer. In this case the * // parameter is not used. * void vBacklightTimerCallback( TimerHandle_t pxTimer ) * { * // The timer expired, therefore 5 seconds must have passed since a key * // was pressed. Switch off the LCD back-light. * vSetBacklightState( BACKLIGHT_OFF ); * } * * // The key press event handler. * void vKeyPressEventHandler( char cKey ) * { * // Ensure the LCD back-light is on, then reset the timer that is * // responsible for turning the back-light off after 5 seconds of * // key inactivity. Wait 10 ticks for the command to be successfully sent * // if it cannot be sent immediately. * vSetBacklightState( BACKLIGHT_ON ); * if( xTimerReset( xBacklightTimer, 100 ) != pdPASS ) * { * // The reset command was not executed successfully. Take appropriate * // action here. * } * * // Perform the rest of the key processing here. * } * * void main( void ) * { * int32_t x; * * // Create then start the one-shot timer that is responsible for turning * // the back-light off if no keys are pressed within a 5 second period. * xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel. * ( 5000 / portTICK_PERIOD_MS), // The timer period in ticks. * pdFALSE, // The timer is a one-shot timer. * 0, // The id is not used by the callback so can take any value. * vBacklightTimerCallback // The callback function that switches the LCD back-light off. * ); * * if( xBacklightTimer == NULL ) * { * // The timer was not created. * } * else * { * // Start the timer. No block time is specified, and even if one was * // it would be ignored because the scheduler has not yet been * // started. * if( xTimerStart( xBacklightTimer, 0 ) != pdPASS ) * { * // The timer could not be set into the Active state. * } * } * * // ... * // Create tasks here. * // ... * * // Starting the scheduler will start the timer running as it has already * // been set into the active state. * vTaskStartScheduler(); * * // Should not reach here. * for( ;; ); * } * @endverbatim */ #define xTimerReset( xTimer, xTicksToWait ) \ xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) /** * BaseType_t xTimerStartFromISR( TimerHandle_t xTimer, * BaseType_t *pxHigherPriorityTaskWoken ); * * A version of xTimerStart() that can be called from an interrupt service * routine. * * @param xTimer The handle of the timer being started/restarted. * * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most * of its time in the Blocked state, waiting for messages to arrive on the timer * command queue. Calling xTimerStartFromISR() writes a message to the timer * command queue, so has the potential to transition the timer service/daemon * task out of the Blocked state. If calling xTimerStartFromISR() causes the * timer service/daemon task to leave the Blocked state, and the timer service/ * daemon task has a priority equal to or greater than the currently executing * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will * get set to pdTRUE internally within the xTimerStartFromISR() function. If * xTimerStartFromISR() sets this value to pdTRUE then a context switch should * be performed before the interrupt exits. * * @return pdFAIL will be returned if the start command could not be sent to * the timer command queue. pdPASS will be returned if the command was * successfully sent to the timer command queue. When the command is actually * processed will depend on the priority of the timer service/daemon task * relative to other tasks in the system, although the timers expiry time is * relative to when xTimerStartFromISR() is actually called. The timer * service/daemon task priority is set by the configTIMER_TASK_PRIORITY * configuration constant. * * Example usage: * @verbatim * // This scenario assumes xBacklightTimer has already been created. When a * // key is pressed, an LCD back-light is switched on. If 5 seconds pass * // without a key being pressed, then the LCD back-light is switched off. In * // this case, the timer is a one-shot timer, and unlike the example given for * // the xTimerReset() function, the key press event handler is an interrupt * // service routine. * * // The callback function assigned to the one-shot timer. In this case the * // parameter is not used. * void vBacklightTimerCallback( TimerHandle_t pxTimer ) * { * // The timer expired, therefore 5 seconds must have passed since a key * // was pressed. Switch off the LCD back-light. * vSetBacklightState( BACKLIGHT_OFF ); * } * * // The key press interrupt service routine. * void vKeyPressEventInterruptHandler( void ) * { * BaseType_t xHigherPriorityTaskWoken = pdFALSE; * * // Ensure the LCD back-light is on, then restart the timer that is * // responsible for turning the back-light off after 5 seconds of * // key inactivity. This is an interrupt service routine so can only * // call FreeRTOS API functions that end in "FromISR". * vSetBacklightState( BACKLIGHT_ON ); * * // xTimerStartFromISR() or xTimerResetFromISR() could be called here * // as both cause the timer to re-calculate its expiry time. * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was * // declared (in this function). * if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) * { * // The start command was not executed successfully. Take appropriate * // action here. * } * * // Perform the rest of the key processing here. * * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch * // should be performed. The syntax required to perform a context switch * // from inside an ISR varies from port to port, and from compiler to * // compiler. Inspect the demos for the port you are using to find the * // actual syntax required. * if( xHigherPriorityTaskWoken != pdFALSE ) * { * // Call the interrupt safe yield function here (actual function * // depends on the FreeRTOS port being used). * } * } * @endverbatim */ #define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) \ xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) /** * BaseType_t xTimerStopFromISR( TimerHandle_t xTimer, * BaseType_t *pxHigherPriorityTaskWoken ); * * A version of xTimerStop() that can be called from an interrupt service * routine. * * @param xTimer The handle of the timer being stopped. * * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most * of its time in the Blocked state, waiting for messages to arrive on the timer * command queue. Calling xTimerStopFromISR() writes a message to the timer * command queue, so has the potential to transition the timer service/daemon * task out of the Blocked state. If calling xTimerStopFromISR() causes the * timer service/daemon task to leave the Blocked state, and the timer service/ * daemon task has a priority equal to or greater than the currently executing * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will * get set to pdTRUE internally within the xTimerStopFromISR() function. If * xTimerStopFromISR() sets this value to pdTRUE then a context switch should * be performed before the interrupt exits. * * @return pdFAIL will be returned if the stop command could not be sent to * the timer command queue. pdPASS will be returned if the command was * successfully sent to the timer command queue. When the command is actually * processed will depend on the priority of the timer service/daemon task * relative to other tasks in the system. The timer service/daemon task * priority is set by the configTIMER_TASK_PRIORITY configuration constant. * * Example usage: * @verbatim * // This scenario assumes xTimer has already been created and started. When * // an interrupt occurs, the timer should be simply stopped. * * // The interrupt service routine that stops the timer. * void vAnExampleInterruptServiceRoutine( void ) * { * BaseType_t xHigherPriorityTaskWoken = pdFALSE; * * // The interrupt has occurred - simply stop the timer. * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined * // (within this function). As this is an interrupt service routine, only * // FreeRTOS API functions that end in "FromISR" can be used. * if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) * { * // The stop command was not executed successfully. Take appropriate * // action here. * } * * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch * // should be performed. The syntax required to perform a context switch * // from inside an ISR varies from port to port, and from compiler to * // compiler. Inspect the demos for the port you are using to find the * // actual syntax required. * if( xHigherPriorityTaskWoken != pdFALSE ) * { * // Call the interrupt safe yield function here (actual function * // depends on the FreeRTOS port being used). * } * } * @endverbatim */ #define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) \ xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U ) /** * BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer, * TickType_t xNewPeriod, * BaseType_t *pxHigherPriorityTaskWoken ); * * A version of xTimerChangePeriod() that can be called from an interrupt * service routine. * * @param xTimer The handle of the timer that is having its period changed. * * @param xNewPeriod The new period for xTimer. Timer periods are specified in * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time * that has been specified in milliseconds. For example, if the timer must * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, * if the timer must expire after 500ms, then xNewPeriod can be set to * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than * or equal to 1000. * * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most * of its time in the Blocked state, waiting for messages to arrive on the timer * command queue. Calling xTimerChangePeriodFromISR() writes a message to the * timer command queue, so has the potential to transition the timer service/ * daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR() * causes the timer service/daemon task to leave the Blocked state, and the * timer service/daemon task has a priority equal to or greater than the * currently executing task (the task that was interrupted), then * *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the * xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets * this value to pdTRUE then a context switch should be performed before the * interrupt exits. * * @return pdFAIL will be returned if the command to change the timers period * could not be sent to the timer command queue. pdPASS will be returned if the * command was successfully sent to the timer command queue. When the command * is actually processed will depend on the priority of the timer service/daemon * task relative to other tasks in the system. The timer service/daemon task * priority is set by the configTIMER_TASK_PRIORITY configuration constant. * * Example usage: * @verbatim * // This scenario assumes xTimer has already been created and started. When * // an interrupt occurs, the period of xTimer should be changed to 500ms. * * // The interrupt service routine that changes the period of xTimer. * void vAnExampleInterruptServiceRoutine( void ) * { * BaseType_t xHigherPriorityTaskWoken = pdFALSE; * * // The interrupt has occurred - change the period of xTimer to 500ms. * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined * // (within this function). As this is an interrupt service routine, only * // FreeRTOS API functions that end in "FromISR" can be used. * if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) * { * // The command to change the timers period was not executed * // successfully. Take appropriate action here. * } * * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch * // should be performed. The syntax required to perform a context switch * // from inside an ISR varies from port to port, and from compiler to * // compiler. Inspect the demos for the port you are using to find the * // actual syntax required. * if( xHigherPriorityTaskWoken != pdFALSE ) * { * // Call the interrupt safe yield function here (actual function * // depends on the FreeRTOS port being used). * } * } * @endverbatim */ #define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) \ xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U ) /** * BaseType_t xTimerResetFromISR( TimerHandle_t xTimer, * BaseType_t *pxHigherPriorityTaskWoken ); * * A version of xTimerReset() that can be called from an interrupt service * routine. * * @param xTimer The handle of the timer that is to be started, reset, or * restarted. * * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most * of its time in the Blocked state, waiting for messages to arrive on the timer * command queue. Calling xTimerResetFromISR() writes a message to the timer * command queue, so has the potential to transition the timer service/daemon * task out of the Blocked state. If calling xTimerResetFromISR() causes the * timer service/daemon task to leave the Blocked state, and the timer service/ * daemon task has a priority equal to or greater than the currently executing * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will * get set to pdTRUE internally within the xTimerResetFromISR() function. If * xTimerResetFromISR() sets this value to pdTRUE then a context switch should * be performed before the interrupt exits. * * @return pdFAIL will be returned if the reset command could not be sent to * the timer command queue. pdPASS will be returned if the command was * successfully sent to the timer command queue. When the command is actually * processed will depend on the priority of the timer service/daemon task * relative to other tasks in the system, although the timers expiry time is * relative to when xTimerResetFromISR() is actually called. The timer service/daemon * task priority is set by the configTIMER_TASK_PRIORITY configuration constant. * * Example usage: * @verbatim * // This scenario assumes xBacklightTimer has already been created. When a * // key is pressed, an LCD back-light is switched on. If 5 seconds pass * // without a key being pressed, then the LCD back-light is switched off. In * // this case, the timer is a one-shot timer, and unlike the example given for * // the xTimerReset() function, the key press event handler is an interrupt * // service routine. * * // The callback function assigned to the one-shot timer. In this case the * // parameter is not used. * void vBacklightTimerCallback( TimerHandle_t pxTimer ) * { * // The timer expired, therefore 5 seconds must have passed since a key * // was pressed. Switch off the LCD back-light. * vSetBacklightState( BACKLIGHT_OFF ); * } * * // The key press interrupt service routine. * void vKeyPressEventInterruptHandler( void ) * { * BaseType_t xHigherPriorityTaskWoken = pdFALSE; * * // Ensure the LCD back-light is on, then reset the timer that is * // responsible for turning the back-light off after 5 seconds of * // key inactivity. This is an interrupt service routine so can only * // call FreeRTOS API functions that end in "FromISR". * vSetBacklightState( BACKLIGHT_ON ); * * // xTimerStartFromISR() or xTimerResetFromISR() could be called here * // as both cause the timer to re-calculate its expiry time. * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was * // declared (in this function). * if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) * { * // The reset command was not executed successfully. Take appropriate * // action here. * } * * // Perform the rest of the key processing here. * * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch * // should be performed. The syntax required to perform a context switch * // from inside an ISR varies from port to port, and from compiler to * // compiler. Inspect the demos for the port you are using to find the * // actual syntax required. * if( xHigherPriorityTaskWoken != pdFALSE ) * { * // Call the interrupt safe yield function here (actual function * // depends on the FreeRTOS port being used). * } * } * @endverbatim */ #define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) \ xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) /** * BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, * void *pvParameter1, * uint32_t ulParameter2, * BaseType_t *pxHigherPriorityTaskWoken ); * * * Used from application interrupt service routines to defer the execution of a * function to the RTOS daemon task (the timer service task, hence this function * is implemented in timers.c and is prefixed with 'Timer'). * * Ideally an interrupt service routine (ISR) is kept as short as possible, but * sometimes an ISR either has a lot of processing to do, or needs to perform * processing that is not deterministic. In these cases * xTimerPendFunctionCallFromISR() can be used to defer processing of a function * to the RTOS daemon task. * * A mechanism is provided that allows the interrupt to return directly to the * task that will subsequently execute the pended callback function. This * allows the callback function to execute contiguously in time with the * interrupt - just as if the callback had executed in the interrupt itself. * * @param xFunctionToPend The function to execute from the timer service/ * daemon task. The function must conform to the PendedFunction_t * prototype. * * @param pvParameter1 The value of the callback function's first parameter. * The parameter has a void * type to allow it to be used to pass any type. * For example, unsigned longs can be cast to a void *, or the void * can be * used to point to a structure. * * @param ulParameter2 The value of the callback function's second parameter. * * @param pxHigherPriorityTaskWoken As mentioned above, calling this function * will result in a message being sent to the timer daemon task. If the * priority of the timer daemon task (which is set using * configTIMER_TASK_PRIORITY in FreeRTOSConfig.h) is higher than the priority of * the currently running task (the task the interrupt interrupted) then * *pxHigherPriorityTaskWoken will be set to pdTRUE within * xTimerPendFunctionCallFromISR(), indicating that a context switch should be * requested before the interrupt exits. For that reason * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the * example code below. * * @return pdPASS is returned if the message was successfully sent to the * timer daemon task, otherwise pdFALSE is returned. * * Example usage: * @verbatim * * // The callback function that will execute in the context of the daemon task. * // Note callback functions must all use this same prototype. * void vProcessInterface( void *pvParameter1, uint32_t ulParameter2 ) * { * BaseType_t xInterfaceToService; * * // The interface that requires servicing is passed in the second * // parameter. The first parameter is not used in this case. * xInterfaceToService = ( BaseType_t ) ulParameter2; * * // ...Perform the processing here... * } * * // An ISR that receives data packets from multiple interfaces * void vAnISR( void ) * { * BaseType_t xInterfaceToService, xHigherPriorityTaskWoken; * * // Query the hardware to determine which interface needs processing. * xInterfaceToService = prvCheckInterfaces(); * * // The actual processing is to be deferred to a task. Request the * // vProcessInterface() callback function is executed, passing in the * // number of the interface that needs processing. The interface to * // service is passed in the second parameter. The first parameter is * // not used in this case. * xHigherPriorityTaskWoken = pdFALSE; * xTimerPendFunctionCallFromISR( vProcessInterface, NULL, ( uint32_t ) xInterfaceToService, &xHigherPriorityTaskWoken ); * * // If xHigherPriorityTaskWoken is now set to pdTRUE then a context * // switch should be requested. The macro used is port specific and will * // be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to * // the documentation page for the port being used. * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * * } * @endverbatim */ BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void * pvParameter1, uint32_t ulParameter2, BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; /** * BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, * void *pvParameter1, * uint32_t ulParameter2, * TickType_t xTicksToWait ); * * * Used to defer the execution of a function to the RTOS daemon task (the timer * service task, hence this function is implemented in timers.c and is prefixed * with 'Timer'). * * @param xFunctionToPend The function to execute from the timer service/ * daemon task. The function must conform to the PendedFunction_t * prototype. * * @param pvParameter1 The value of the callback function's first parameter. * The parameter has a void * type to allow it to be used to pass any type. * For example, unsigned longs can be cast to a void *, or the void * can be * used to point to a structure. * * @param ulParameter2 The value of the callback function's second parameter. * * @param xTicksToWait Calling this function will result in a message being * sent to the timer daemon task on a queue. xTicksToWait is the amount of * time the calling task should remain in the Blocked state (so not using any * processing time) for space to become available on the timer queue if the * queue is found to be full. * * @return pdPASS is returned if the message was successfully sent to the * timer daemon task, otherwise pdFALSE is returned. * */ BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void * pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** * const char * const pcTimerGetName( TimerHandle_t xTimer ); * * Returns the name that was assigned to a timer when the timer was created. * * @param xTimer The handle of the timer being queried. * * @return The name assigned to the timer specified by the xTimer parameter. */ const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ /** * void vTimerSetReloadMode( TimerHandle_t xTimer, const BaseType_t xAutoReload ); * * Updates a timer to be either an auto-reload timer, in which case the timer * automatically resets itself each time it expires, or a one-shot timer, in * which case the timer will only expire once unless it is manually restarted. * * @param xTimer The handle of the timer being updated. * * @param xAutoReload If xAutoReload is set to pdTRUE then the timer will * expire repeatedly with a frequency set by the timer's period (see the * xTimerPeriodInTicks parameter of the xTimerCreate() API function). If * xAutoReload is set to pdFALSE then the timer will be a one-shot timer and * enter the dormant state after it expires. */ void vTimerSetReloadMode( TimerHandle_t xTimer, const BaseType_t xAutoReload ) PRIVILEGED_FUNCTION; /** * BaseType_t xTimerGetReloadMode( TimerHandle_t xTimer ); * * Queries a timer to determine if it is an auto-reload timer, in which case the timer * automatically resets itself each time it expires, or a one-shot timer, in * which case the timer will only expire once unless it is manually restarted. * * @param xTimer The handle of the timer being queried. * * @return If the timer is an auto-reload timer then pdTRUE is returned, otherwise * pdFALSE is returned. */ BaseType_t xTimerGetReloadMode( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /** * UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer ); * * Queries a timer to determine if it is an auto-reload timer, in which case the timer * automatically resets itself each time it expires, or a one-shot timer, in * which case the timer will only expire once unless it is manually restarted. * * @param xTimer The handle of the timer being queried. * * @return If the timer is an auto-reload timer then pdTRUE is returned, otherwise * pdFALSE is returned. */ UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /** * TickType_t xTimerGetPeriod( TimerHandle_t xTimer ); * * Returns the period of a timer. * * @param xTimer The handle of the timer being queried. * * @return The period of the timer in ticks. */ TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /** * TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ); * * Returns the time in ticks at which the timer will expire. If this is less * than the current tick count then the expiry time has overflowed from the * current time. * * @param xTimer The handle of the timer being queried. * * @return If the timer is running then the time in ticks at which the timer * will next expire is returned. If the timer is not running then the return * value is undefined. */ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /* * Functions beyond this part are not part of the public API and are intended * for use by the kernel only. */ BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION; BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; #if ( configUSE_TRACE_FACILITY == 1 ) void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber ) PRIVILEGED_FUNCTION; UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; #endif #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) /** * task.h * @code{c} * void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, StackType_t ** ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) * @endcode * * This function is used to provide a statically allocated block of memory to FreeRTOS to hold the Timer Task TCB. This function is required when * configSUPPORT_STATIC_ALLOCATION is set. For more information see this URI: https://www.FreeRTOS.org/a00110.html#configSUPPORT_STATIC_ALLOCATION * * @param ppxTimerTaskTCBBuffer A handle to a statically allocated TCB buffer * @param ppxTimerTaskStackBuffer A handle to a statically allocated Stack buffer for the idle task * @param pulTimerTaskStackSize A pointer to the number of elements that will fit in the allocated stack buffer */ void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, StackType_t ** ppxTimerTaskStackBuffer, uint32_t * pulTimerTaskStackSize ); #endif /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* TIMERS_H */ ================================================ FILE: FreeRTOS-comparison/list.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #include "FreeRTOS.h" #include "list.h" /* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified * because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be * defined for the header files above, but not in this file, in order to * generate the correct privileged Vs unprivileged linkage and placement. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ /*----------------------------------------------------------- * PUBLIC LIST API documented in list.h *----------------------------------------------------------*/ void vListInitialise( List_t * const pxList ) { /* The list structure contains a list item which is used to mark the * end of the list. To initialise the list the list end is inserted * as the only list entry. */ pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) ); /* The list end value is the highest possible value in the list to * ensure it remains at the end of the list. */ pxList->xListEnd.xItemValue = portMAX_DELAY; /* The list end next and previous pointers point to itself so we know * when the list is empty. */ pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ /* Initialize the remaining fields of xListEnd when it is a proper ListItem_t */ #if ( configUSE_MINI_LIST_ITEM == 0 ) { pxList->xListEnd.pvOwner = NULL; pxList->xListEnd.pxContainer = NULL; listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) ); } #endif pxList->uxNumberOfItems = ( UBaseType_t ) 0U; /* Write known values into the list if * configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); } /*-----------------------------------------------------------*/ void vListInitialiseItem( ListItem_t * const pxItem ) { /* Make sure the list item is not recorded as being on a list. */ pxItem->pxContainer = NULL; /* Write known values into the list item if * configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); } /*-----------------------------------------------------------*/ void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) { ListItem_t * const pxIndex = pxList->pxIndex; /* Only effective when configASSERT() is also defined, these tests may catch * the list data structures being overwritten in memory. They will not catch * data errors caused by incorrect configuration or use of FreeRTOS. */ listTEST_LIST_INTEGRITY( pxList ); listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); /* Insert a new list item into pxList, but rather than sort the list, * makes the new list item the last item to be removed by a call to * listGET_OWNER_OF_NEXT_ENTRY(). */ pxNewListItem->pxNext = pxIndex; pxNewListItem->pxPrevious = pxIndex->pxPrevious; /* Only used during decision coverage testing. */ mtCOVERAGE_TEST_DELAY(); pxIndex->pxPrevious->pxNext = pxNewListItem; pxIndex->pxPrevious = pxNewListItem; /* Remember which list the item is in. */ pxNewListItem->pxContainer = pxList; ( pxList->uxNumberOfItems )++; } /*-----------------------------------------------------------*/ void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) { ListItem_t * pxIterator; const TickType_t xValueOfInsertion = pxNewListItem->xItemValue; /* Only effective when configASSERT() is also defined, these tests may catch * the list data structures being overwritten in memory. They will not catch * data errors caused by incorrect configuration or use of FreeRTOS. */ listTEST_LIST_INTEGRITY( pxList ); listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); /* Insert the new list item into the list, sorted in xItemValue order. * * If the list already contains a list item with the same item value then the * new list item should be placed after it. This ensures that TCBs which are * stored in ready lists (all of which have the same xItemValue value) get a * share of the CPU. However, if the xItemValue is the same as the back marker * the iteration loop below will not end. Therefore the value is checked * first, and the algorithm slightly modified if necessary. */ if( xValueOfInsertion == portMAX_DELAY ) { pxIterator = pxList->xListEnd.pxPrevious; } else { /* *** NOTE *********************************************************** * If you find your application is crashing here then likely causes are * listed below. In addition see https://www.FreeRTOS.org/FAQHelp.html for * more tips, and ensure configASSERT() is defined! * https://www.FreeRTOS.org/a00110.html#configASSERT * * 1) Stack overflow - * see https://www.FreeRTOS.org/Stacks-and-stack-overflow-checking.html * 2) Incorrect interrupt priority assignment, especially on Cortex-M * parts where numerically high priority values denote low actual * interrupt priorities, which can seem counter intuitive. See * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html and the definition * of configMAX_SYSCALL_INTERRUPT_PRIORITY on * https://www.FreeRTOS.org/a00110.html * 3) Calling an API function from within a critical section or when * the scheduler is suspended, or calling an API function that does * not end in "FromISR" from an interrupt. * 4) Using a queue or semaphore before it has been initialised or * before the scheduler has been started (are interrupts firing * before vTaskStartScheduler() has been called?). * 5) If the FreeRTOS port supports interrupt nesting then ensure that * the priority of the tick interrupt is at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. **********************************************************************/ for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */ { /* There is nothing to do here, just iterating to the wanted * insertion position. */ } } pxNewListItem->pxNext = pxIterator->pxNext; pxNewListItem->pxNext->pxPrevious = pxNewListItem; pxNewListItem->pxPrevious = pxIterator; pxIterator->pxNext = pxNewListItem; /* Remember which list the item is in. This allows fast removal of the * item later. */ pxNewListItem->pxContainer = pxList; ( pxList->uxNumberOfItems )++; } /*-----------------------------------------------------------*/ UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) { /* The list item knows which list it is in. Obtain the list from the list * item. */ List_t * const pxList = pxItemToRemove->pxContainer; pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; /* Only used during decision coverage testing. */ mtCOVERAGE_TEST_DELAY(); /* Make sure the index is left pointing to a valid item. */ if( pxList->pxIndex == pxItemToRemove ) { pxList->pxIndex = pxItemToRemove->pxPrevious; } else { mtCOVERAGE_TEST_MARKER(); } pxItemToRemove->pxContainer = NULL; ( pxList->uxNumberOfItems )--; return pxList->uxNumberOfItems; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/manifest.yml ================================================ name : "FreeRTOS-Kernel" version: "v10.5.1" description: "FreeRTOS Kernel." license: "MIT" ================================================ FILE: FreeRTOS-comparison/portable/ARMClang/Use-the-GCC-ports.txt ================================================ The FreeRTOS GCC port layer also builds and works with the ARMClang compiler. To use the ARMClang compiler build the port files from FreeRTOS/Source/portable/GCC. ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/ReadMe.txt ================================================ This directory tree contains the master copy of the FreeeRTOS Armv8-M and Armv8.1-M ports. 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 release. If your Armv8-M and Armv8.1-M application uses TrustZone then use the files from the FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85] directories. If your Armv8-M and Armv8.1-M application does not use TrustZone then use the files from the FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85]_NTZ directories. ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/copy_files.py ================================================ #/* # * FreeRTOS Kernel V10.5.1 # * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. # * # * SPDX-License-Identifier: MIT # * # * Permission is hereby granted, free of charge, to any person obtaining a copy of # * this software and associated documentation files (the "Software"), to deal in # * the Software without restriction, including without limitation the rights to # * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of # * the Software, and to permit persons to whom the Software is furnished to do so, # * subject to the following conditions: # * # * The above copyright notice and this permission notice shall be included in all # * copies or substantial portions of the Software. # * # * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS # * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR # * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER # * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # * # * https://www.FreeRTOS.org # * https://github.com/FreeRTOS # * # */ import os import shutil _THIS_FILE_DIRECTORY_ = os.path.dirname(os.path.realpath(__file__)) _FREERTOS_PORTABLE_DIRECTORY_ = os.path.dirname(_THIS_FILE_DIRECTORY_) _COMPILERS_ = ['GCC', 'IAR'] _ARCH_NS_ = ['ARM_CM85', 'ARM_CM85_NTZ', 'ARM_CM55', 'ARM_CM55_NTZ', 'ARM_CM33', 'ARM_CM33_NTZ', 'ARM_CM23', 'ARM_CM23_NTZ'] _ARCH_S_ = ['ARM_CM85', 'ARM_CM55', 'ARM_CM33', 'ARM_CM23'] # Files to be compiled in the Secure Project _SECURE_COMMON_FILE_PATHS_ = [ os.path.join('secure', 'context'), os.path.join('secure', 'heap'), os.path.join('secure', 'init'), os.path.join('secure', 'macros') ] _SECURE_PORTABLE_FILE_PATHS_ = { 'GCC':{ 'ARM_CM23':[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM23')], 'ARM_CM33':[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')], 'ARM_CM55':[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')], 'ARM_CM85':[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')] }, 'IAR':{ 'ARM_CM23':[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM23')], 'ARM_CM33':[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')], 'ARM_CM55':[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')], 'ARM_CM85':[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')] } } # Files to be compiled in the Non-Secure Project _NONSECURE_COMMON_FILE_PATHS_ = [ 'non_secure' ] _NONSECURE_PORTABLE_FILE_PATHS_ = { 'GCC':{ 'ARM_CM23' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM23')], 'ARM_CM23_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM23_NTZ')], 'ARM_CM33' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33')], 'ARM_CM33_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ')], 'ARM_CM55' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'portasm.c'), os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM55', 'portmacro.h')], 'ARM_CM55_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'portasm.c'), os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM55', 'portmacro.h')], 'ARM_CM85' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'portasm.c'), os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM85', 'portmacro.h')], 'ARM_CM85_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'portasm.c'), os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM85', 'portmacro.h')] }, 'IAR':{ 'ARM_CM23' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM23')], 'ARM_CM23_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM23_NTZ')], 'ARM_CM33' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33')], 'ARM_CM33_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ')], 'ARM_CM55' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'portasm.s'), os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM55', 'portmacro.h')], 'ARM_CM55_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'portasm.s'), os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM55', 'portmacro.h')], 'ARM_CM85' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'portasm.s'), os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM85', 'portmacro.h')], 'ARM_CM85_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'portasm.s'), os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM85', 'portmacro.h')] }, } def copy_files_in_dir(src_abs_path, dst_abs_path): if os.path.isfile(src_abs_path): print('Src: {}'.format(src_abs_path)) print('Dst: {}\n'.format(dst_abs_path)) shutil.copy2(src_abs_path, dst_abs_path) else: for src_file in os.listdir(src_abs_path): src_file_abs_path = os.path.join(src_abs_path, src_file) if os.path.isfile(src_file_abs_path) and src_file != 'ReadMe.txt': if not os.path.exists(dst_abs_path): os.makedirs(dst_abs_path) print('Src: {}'.format(src_file_abs_path)) print('Dst: {}\n'.format(dst_abs_path)) shutil.copy2(src_file_abs_path, dst_abs_path) def copy_common_files_for_compiler_and_arch(compiler, arch, src_paths, dst_path): for src_path in src_paths: src_abs_path = os.path.join(_THIS_FILE_DIRECTORY_, src_path) dst_abs_path = os.path.join(_FREERTOS_PORTABLE_DIRECTORY_, compiler, arch, dst_path) copy_files_in_dir(src_abs_path, dst_abs_path) def copy_portable_files_for_compiler_and_arch(compiler, arch, src_paths, dst_path): for src_path in src_paths[compiler][arch]: src_abs_path = os.path.join(_THIS_FILE_DIRECTORY_, src_path) dst_abs_path = os.path.join(_FREERTOS_PORTABLE_DIRECTORY_, compiler, arch, dst_path) copy_files_in_dir(src_abs_path, dst_abs_path) def copy_files(): # Copy Secure Files for compiler in _COMPILERS_: for arch in _ARCH_S_: copy_common_files_for_compiler_and_arch(compiler, arch, _SECURE_COMMON_FILE_PATHS_, 'secure') copy_portable_files_for_compiler_and_arch(compiler, arch, _SECURE_PORTABLE_FILE_PATHS_, 'secure') # Copy Non-Secure Files for compiler in _COMPILERS_: for arch in _ARCH_NS_: copy_common_files_for_compiler_and_arch(compiler, arch, _NONSECURE_COMMON_FILE_PATHS_, 'non_secure') copy_portable_files_for_compiler_and_arch(compiler, arch, _NONSECURE_PORTABLE_FILE_PATHS_, 'non_secure') def main(): copy_files() if __name__ == '__main__': main() ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/ReadMe.txt ================================================ This directory tree contains the master copy of the FreeRTOS Armv8-M and Armv8.1-M ports. 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 release. If your Armv8-M/Armv8.1-M application uses TrustZone then use the files from the FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85] directories. If your Armv8-M/Armv8.1-M application does not use TrustZone then use the files from the FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85]_NTZ directories. ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /* Portasm includes. */ #include "portasm.h" #if ( configENABLE_TRUSTZONE == 1 ) /* Secure components includes. */ #include "secure_context.h" #include "secure_init.h" #endif /* configENABLE_TRUSTZONE */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /** * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS * on the secure side. The following are the valid configuration seetings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 * * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 * * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 */ #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. #endif /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the SCB. */ #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the FPU. */ #define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) #define portMPU_RLAR_REGION_ENABLE ( 1UL ) /* Enable privileged access to unmapped region. */ #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /*-----------------------------------------------------------*/ /** * @brief The maximum 24-bit number. * * It is needed because the systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /** * @brief A fiddle factor to estimate the number of SysTick counts that would * have occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) /** * @brief Initial EXC_RETURN value. * * FF FF FF FD * 1111 1111 1111 1111 1111 1111 1111 1101 * * Bit[6] - 1 --> The exception was taken from the Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 1 --> The exception was taken to the Secure state. */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else /** * @brief Initial EXC_RETURN value. * * FF FF FF BC * 1111 1111 1111 1111 1111 1111 1011 1100 * * Bit[6] - 0 --> The exception was taken from the Non-Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 0 --> The exception was taken to the Non-Secure state. */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ /** * @brief CONTROL register privileged bit mask. * * Bit[0] in CONTROL register tells the privilege: * Bit[0] = 0 ==> The task is privileged. * Bit[0] = 1 ==> The task is not privileged. */ #define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) /** * @brief Initial CONTROL register values. */ #define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) #define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) /** * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /** * @brief 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /** * @brief If portPRELOAD_REGISTERS then registers will be given an initial value * when a task is created. This helps in debugging at the cost of code size. */ #define portPRELOAD_REGISTERS 1 /** * @brief A task is created without a secure context, and must call * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes * any secure calls. */ #define portNO_SECURE_CONTEXT 0 /*-----------------------------------------------------------*/ /** * @brief Used to catch tasks that attempt to return from their implementing * function. */ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) /** * @brief Setup the Memory Protection Unit (MPU). */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) /** * @brief Setup the Floating Point Unit (FPU). */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ /** * @brief Setup the timer to generate the tick interrupts. * * The implementation in this file is weak to allow application writers to * change the timer used to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /** * @brief Checks whether the current execution context is interrupt. * * @return pdTRUE if the current execution context is interrupt, pdFALSE * otherwise. */ BaseType_t xPortIsInsideInterrupt( void ); /** * @brief Yield the processor. */ void vPortYield( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ void vPortExitCritical( void ) PRIVILEGED_FUNCTION; /** * @brief SysTick handler. */ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; /** * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. */ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Saved as part of the task context to indicate which context the * task is using on the secure side. */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ #if ( configUSE_TICKLESS_IDLE == 1 ) /** * @brief The number of SysTick increments that make up one tick period. */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; /** * @brief The maximum number of tick periods that can be suppressed is * limited by the 24 bit resolution of the SysTick timer. */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; /** * @brief Compensate for the CPU cycles that pass while the SysTick is * stopped (low power functionality only). */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). Artificially force an assert() * to be triggered if configASSERT() is defined, then stop here so * application writers can catch the error. */ configASSERT( ulCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being * defined but never called. ulDummy is used purely to quieten other * warnings about code appearing after this function is called - making * ulDummy volatile makes the compiler think the function could return * and therefore not output an 'unreachable code' warning for code that * appears after it. */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; extern uint32_t * __unprivileged_flash_start__; extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* if defined( __ARMCC_VERSION ) */ /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; extern uint32_t __unprivileged_flash_start__[]; extern uint32_t __unprivileged_flash_end__[]; extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check that the MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* MAIR0 - Index 0. */ portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); /* MAIR0 - Index 1. */ portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* Setup privileged flash as Read Only so that privileged tasks can * read it but not modify. */ portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged flash as Read Only by both privileged and * unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged syscalls flash as Read Only by both privileged * and unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup RAM containing kernel data for privileged access only. */ portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Enable mem fault. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; /* Enable MPU with privileged background access i.e. unmapped * regions have privileged access. */ portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) { /* Enable non-secure access to the FPU. */ SecureInit_EnableNSFPUAccess(); } #endif /* configENABLE_TRUSTZONE */ /* CP10 = 11 ==> Full access to FPU i.e. both privileged and * unprivileged code should be able to access FPU. CP11 should be * programmed to the same value as CP10. */ *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) ); /* ASPEN = 1 ==> Hardware should automatically preserve floating point * context on exception entry and restore on exception return. * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ void vPortYield( void ) /* PRIVILEGED_FUNCTION */ { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ { portDISABLE_INTERRUPTS(); ulCriticalNesting++; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ { configASSERT( ulCriticalNesting ); ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { #if ( configENABLE_MPU == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ #endif /* configENABLE_MPU */ uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) uint32_t ulR0, ulR1; extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ #endif /* configENABLE_TRUSTZONE */ uint8_t ucSVCNumber; /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ ulPC = pulCallerStackAddress[ 6 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { #if ( configENABLE_TRUSTZONE == 1 ) case portSVC_ALLOCATE_SECURE_CONTEXT: /* R0 contains the stack size passed as parameter to the * vPortAllocateSecureContext function. */ ulR0 = pulCallerStackAddress[ 0 ]; #if ( configENABLE_MPU == 1 ) { /* Read the CONTROL register value. */ __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); /* The task that raised the SVC is privileged if Bit[0] * in the CONTROL register is 0. */ ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: /* R0 contains TCB being freed and R1 contains the secure * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) { /* De-prioritize the non-secure exceptions so that the * non-secure pendSV runs at the lowest priority. */ SecureInit_DePrioritizeNSExceptions(); /* Initialize the secure context management system. */ SecureContext_Init(); } #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_FPU == 1 ) { /* Setup the Floating Point Unit (FPU). */ prvSetupFPU(); } #endif /* configENABLE_FPU */ /* Setup the context of the first task so that the first task starts * executing. */ vRestoreContextOfFirstTask(); break; #if ( configENABLE_MPU == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the svc was raised from any of * the system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { vRaisePrivilege(); } break; #endif /* configENABLE_MPU */ default: /* Incorrect SVC call. */ configASSERT( pdFALSE ); } } /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #if ( configENABLE_MPU == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /* *INDENT-ON* */ { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #endif /* portPRELOAD_REGISTERS */ return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ prvSetupMPU(); } #endif /* configENABLE_MPU */ /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; /* Start the first task. */ vStartFirstTask(); /* Should never get here as the tasks will now be executing. Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* Setup MAIR0. */ xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ if( ulStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged * SRAM is already protected using an MPU region and ARMv8-M does * not allow overlapping MPU regions. */ if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) { xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; } else { /* Define the region that allows access to the stack. */ ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); } } /* User supplied configurable regions. */ for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) { /* If xRegions is NULL i.e. the task has not specified any MPU * region, the else part ensures that all the configurable MPU * regions are invalidated. */ if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) { /* Translate the generic region definition contained in xRegions * into the ARMv8 specific MPU settings that are then stored in * xMPUSettings. */ ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; /* Start address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ); /* RO/RW. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); } else { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); } /* XN. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); } /* End Address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { /* Attr1 in MAIR0 is configured as device memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; } else { /* Attr0 in MAIR0 is configured as normal memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; } } else { /* Invalidate the region. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; } lIndex++; } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. Interrupt Program * Status Register (IPSR) holds the exception number of the currently-executing * exception or zero for Thread mode.*/ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION * is defined correctly and privileged functions are placed in correct sections. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Portasm includes. */ #include "portasm.h" /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #if ( configENABLE_FPU == 1 ) #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " movs r5, #1 \n"/* r5 = 1. */ " bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ " str r4, [r2] \n"/* Disable MPU. */ " \n" " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r4, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ " movs r5, #4 \n"/* r5 = 4. */ " str r5, [r2] \n"/* Program RNR = 4. */ " ldmia r3!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */ " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ " stmia r4!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */ " movs r5, #5 \n"/* r5 = 5. */ " str r5, [r2] \n"/* Program RNR = 5. */ " ldmia r3!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */ " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ " stmia r4!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */ " movs r5, #6 \n"/* r5 = 6. */ " str r5, [r2] \n"/* Program RNR = 6. */ " ldmia r3!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */ " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ " stmia r4!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */ " movs r5, #7 \n"/* r5 = 7. */ " str r5, [r2] \n"/* Program RNR = 7. */ " ldmia r3!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */ " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ " stmia r4!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */ " \n" " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " movs r5, #1 \n"/* r5 = 1. */ " orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ " str r4, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ " ldr r5, xSecureContextConst2 \n" " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ " msr control, r3 \n"/* Set this task's CONTROL value. */ " 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. */ " isb \n" " bx r4 \n"/* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, xSecureContextConst2 \n" " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ " movs r1, #2 \n"/* r1 = 2. */ " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ " 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. */ " isb \n" " bx r3 \n"/* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" "xSecureContextConst2: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst2: .word 0xe000ed94 \n" "xMAIR0Const2: .word 0xe000edc0 \n" "xRNRConst2: .word 0xe000ed98 \n" "xRBARConst2: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " movs r1, #1 \n"/* r1 = 1. */ " 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. */ " movs r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ " bx lr \n"/* Return. */ " running_privileged: \n" " movs r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n"/* Return. */ " \n" " .align 4 \n" ::: "r0", "r1", "memory" ); } /*-----------------------------------------------------------*/ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* Read the CONTROL register. */ " movs r1, #1 \n"/* r1 = 1. */ " bics r0, r1 \n"/* Clear the bit 0. */ " msr control, r0 \n"/* Write back the new CONTROL value. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "r1", "memory" ); } /*-----------------------------------------------------------*/ void vResetPrivilege( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " movs r1, #1 \n"/* r1 = 1. */ " orrs r0, r1 \n"/* r0 = r0 | r1. */ " msr control, r0 \n"/* CONTROL = r0. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "r1", "memory" ); } /*-----------------------------------------------------------*/ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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"/* The first entry in vector table is stack pointer. */ " msr msp, r0 \n"/* Set the MSP back to the start of the stack. */ " cpsie i \n"/* Globally enable interrupts. */ " dsb \n" " isb \n" " svc %0 \n"/* System call to start the first task. */ " nop \n" " \n" " .align 4 \n" "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } /*-----------------------------------------------------------*/ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, PRIMASK \n" " cpsid i \n" " bx lr \n" ::: "memory" ); } /*-----------------------------------------------------------*/ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " msr PRIMASK, r0 \n" " bx lr \n" ::: "memory" ); } /*-----------------------------------------------------------*/ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" " 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 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.*/ " mrs r2, psp \n"/* Read PSP in r2. */ " \n" " cbz r0, save_ns_context \n"/* No secure context to save. */ " push {r0-r2, r14} \n" " bl SecureContext_SaveContext \n"/* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r0-r3} \n"/* LR is now in 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. */ " 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. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ " str r2, [r1] \n"/* Save the new top of stack in TCB. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r3, control \n"/* r3 = CONTROL. */ " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ " 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. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ " b select_next_task \n" " \n" " save_ns_context: \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ " str r2, [r1] \n"/* Save the new top of stack in TCB. */ " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ " stmia r2!, {r4-r7} \n"/* Store the low registers that are not saved automatically. */ " mov r4, r8 \n"/* r4 = r8. */ " mov r5, r9 \n"/* r5 = r9. */ " mov r6, r10 \n"/* r6 = r10. */ " mov r7, r11 \n"/* r7 = r11. */ " stmia r2!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r3, control \n"/* r3 = CONTROL. */ " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ " subs r2, r2, #48 \n"/* r2 = r2 - 48. */ " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ " 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. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " stmia r2!, {r0, r1, r3-r7} \n"/* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ " mov r4, r8 \n"/* r4 = r8. */ " mov r5, r9 \n"/* r5 = r9. */ " mov r6, r10 \n"/* r6 = r10. */ " mov r7, r11 \n"/* r7 = r11. */ " stmia r2!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ #endif /* configENABLE_MPU */ " \n" " select_next_task: \n" " cpsid i \n" " bl vTaskSwitchContext \n" " cpsie i \n" " \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ " movs r5, #1 \n"/* r5 = 1. */ " bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ " str r4, [r3] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ " str r4, [r3] \n"/* Program MAIR0. */ " ldr r4, xRNRConst \n"/* r4 = 0xe000ed98 [Location of RNR]. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " movs r5, #4 \n"/* r5 = 4. */ " str r5, [r4] \n"/* Program RNR = 4. */ " ldmia r1!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */ " movs r5, #5 \n"/* r5 = 5. */ " str r5, [r4] \n"/* Program RNR = 5. */ " ldmia r1!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */ " movs r5, #6 \n"/* r5 = 6. */ " str r5, [r4] \n"/* Program RNR = 6. */ " ldmia r1!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */ " movs r5, #7 \n"/* r5 = 7. */ " str r5, [r4] \n"/* Program RNR = 7. */ " ldmia r1!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */ " \n" " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ " movs r5, #1 \n"/* r5 = 1. */ " orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ " str r4, [r3] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ " mov lr, r4 \n"/* LR = r4. */ " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( 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. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " push {r2, r4} \n" " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r2, r4} \n" " 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. */ " 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. */ " bx lr \n" #else /* configENABLE_MPU */ " 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. */ " mov lr, r4 \n"/* LR = r4. */ " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( 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. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " push {r2, r4} \n" " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r2, r4} \n" " 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. */ " 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. */ " bx lr \n" #endif /* configENABLE_MPU */ " \n" " restore_ns_context: \n" " adds r2, r2, #16 \n"/* Move to the high registers. */ " ldmia r2!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ " mov r8, r4 \n"/* r8 = r4. */ " mov r9, r5 \n"/* r9 = r5. */ " mov r10, r6 \n"/* r10 = r6. */ " mov r11, r7 \n"/* r11 = r7. */ " msr psp, r2 \n"/* Remember the new top of stack for the task. */ " subs r2, r2, #32 \n"/* Go back to the low registers. */ " ldmia r2!, {r4-r7} \n"/* Restore the low registers that are not automatically restored. */ " bx lr \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" "xSecureContextConst: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst: .word 0xe000ed94 \n" "xMAIR0Const: .word 0xe000edc0 \n" "xRNRConst: .word 0xe000ed98 \n" "xRBARConst: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } /*-----------------------------------------------------------*/ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " movs r0, #4 \n" " mov r1, lr \n" " tst r0, r1 \n" " beq stacking_used_msp \n" " mrs r0, psp \n" " ldr r2, svchandler_address_const \n" " bx r2 \n" " stacking_used_msp: \n" " mrs r0, msp \n" " ldr r2, svchandler_address_const \n" " bx r2 \n" " \n" " .align 4 \n" "svchandler_address_const: .word vPortSVCHandler_C \n" ); } /*-----------------------------------------------------------*/ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " svc %0 \n"/* Secure context is allocated in the supervisor call. */ " bx lr \n"/* Return. */ ::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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. */ " cmp r1, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */ " bne free_secure_context \n"/* Branch if r1 != 0. */ " bx lr \n"/* There is no secure context (xSecureContext is NULL). */ " free_secure_context: \n" " svc %0 \n"/* Secure context is freed in the supervisor call. */ " bx lr \n"/* Return. */ ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M23" #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portasm.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION * is defined correctly and privileged functions are placed in correct sections. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Portasm includes. */ #include "portasm.h" /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #if ( configENABLE_FPU == 1 ) #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " movs r4, #1 \n"/* r4 = 1. */ " bics r3, r4 \n"/* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ " str r3, [r2] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r4, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " movs r4, #4 \n"/* r4 = 4. */ " str r4, [r2] \n"/* Program RNR = 4. */ " ldmia r1!, {r5,r6} \n"/* Read first set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r5,r6} \n"/* Write first set of RBAR/RLAR registers. */ " movs r4, #5 \n"/* r4 = 5. */ " str r4, [r2] \n"/* Program RNR = 5. */ " ldmia r1!, {r5,r6} \n"/* Read second set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r5,r6} \n"/* Write second set of RBAR/RLAR registers. */ " movs r4, #6 \n"/* r4 = 6. */ " str r4, [r2] \n"/* Program RNR = 6. */ " ldmia r1!, {r5,r6} \n"/* Read third set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r5,r6} \n"/* Write third set of RBAR/RLAR registers. */ " movs r4, #7 \n"/* r4 = 7. */ " str r4, [r2] \n"/* Program RNR = 7. */ " ldmia r1!, {r5,r6} \n"/* Read fourth set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r5,r6} \n"/* Write fourth set of RBAR/RLAR registers. */ " \n" " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " movs r4, #1 \n"/* r4 = 1. */ " orrs r3, r4 \n"/* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ " str r3, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ " msr control, r2 \n"/* Set this task's CONTROL value. */ " 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. */ " isb \n" " bx r3 \n"/* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ " movs r1, #2 \n"/* r1 = 2. */ " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ " 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. */ " isb \n" " bx r2 \n"/* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst2: .word 0xe000ed94 \n" "xMAIR0Const2: .word 0xe000edc0 \n" "xRNRConst2: .word 0xe000ed98 \n" "xRBARConst2: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " movs r1, #1 \n"/* r1 = 1. */ " 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. */ " movs r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ " bx lr \n"/* Return. */ " running_privileged: \n" " movs r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n"/* Return. */ " \n" " .align 4 \n" ::: "r0", "r1", "memory" ); } /*-----------------------------------------------------------*/ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* Read the CONTROL register. */ " movs r1, #1 \n"/* r1 = 1. */ " bics r0, r1 \n"/* Clear the bit 0. */ " msr control, r0 \n"/* Write back the new CONTROL value. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "r1", "memory" ); } /*-----------------------------------------------------------*/ void vResetPrivilege( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " movs r1, #1 \n"/* r1 = 1. */ " orrs r0, r1 \n"/* r0 = r0 | r1. */ " msr control, r0 \n"/* CONTROL = r0. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "r1", "memory" ); } /*-----------------------------------------------------------*/ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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"/* The first entry in vector table is stack pointer. */ " msr msp, r0 \n"/* Set the MSP back to the start of the stack. */ " cpsie i \n"/* Globally enable interrupts. */ " dsb \n" " isb \n" " svc %0 \n"/* System call to start the first task. */ " nop \n" " \n" " .align 4 \n" "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } /*-----------------------------------------------------------*/ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, PRIMASK \n" " cpsid i \n" " bx lr \n" ::: "memory" ); } /*-----------------------------------------------------------*/ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " msr PRIMASK, r0 \n" " bx lr \n" ::: "memory" ); } /*-----------------------------------------------------------*/ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, psp \n"/* Read PSP in r0. */ " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) " subs r0, r0, #44 \n"/* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */ " str r0, [r1] \n"/* Save the new top of stack in TCB. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r2, control \n"/* r2 = CONTROL. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " stmia r0!, {r1-r7} \n"/* Store on the stack - PSPLIM, CONTROL, LR and low registers that are not automatically saved. */ " mov r4, r8 \n"/* r4 = r8. */ " mov r5, r9 \n"/* r5 = r9. */ " mov r6, r10 \n"/* r6 = r10. */ " mov r7, r11 \n"/* r7 = r11. */ " stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ #else /* configENABLE_MPU */ " 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. */ " mrs r2, psplim \n"/* r2 = PSPLIM. */ " 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. */ " mov r4, r8 \n"/* r4 = r8. */ " mov r5, r9 \n"/* r5 = r9. */ " mov r6, r10 \n"/* r6 = r10. */ " mov r7, r11 \n"/* r7 = r11. */ " stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ #endif /* configENABLE_MPU */ " \n" " cpsid i \n" " bl vTaskSwitchContext \n" " cpsie i \n" " \n" " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " movs r4, #1 \n"/* r4 = 1. */ " bics r3, r4 \n"/* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ " str r3, [r2] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r4, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " movs r4, #4 \n"/* r4 = 4. */ " str r4, [r2] \n"/* Program RNR = 4. */ " ldmia r1!, {r5,r6} \n"/* Read first set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r5,r6} \n"/* Write first set of RBAR/RLAR registers. */ " movs r4, #5 \n"/* r4 = 5. */ " str r4, [r2] \n"/* Program RNR = 5. */ " ldmia r1!, {r5,r6} \n"/* Read second set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r5,r6} \n"/* Write second set of RBAR/RLAR registers. */ " movs r4, #6 \n"/* r4 = 6. */ " str r4, [r2] \n"/* Program RNR = 6. */ " ldmia r1!, {r5,r6} \n"/* Read third set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r5,r6} \n"/* Write third set of RBAR/RLAR registers. */ " movs r4, #7 \n"/* r4 = 7. */ " str r4, [r2] \n"/* Program RNR = 7. */ " ldmia r1!, {r5,r6} \n"/* Read fourth set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r5,r6} \n"/* Write fourth set of RBAR/RLAR registers. */ " \n" " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " movs r4, #1 \n"/* r4 = 1. */ " orrs r3, r4 \n"/* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ " str r3, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " adds r0, r0, #28 \n"/* Move to the high registers. */ " ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ " mov r8, r4 \n"/* r8 = r4. */ " mov r9, r5 \n"/* r9 = r5. */ " mov r10, r6 \n"/* r10 = r6. */ " mov r11, r7 \n"/* r11 = r7. */ " msr psp, r0 \n"/* Remember the new top of stack for the task. */ " subs r0, r0, #44 \n"/* Move to the starting of the saved context. */ " ldmia r0!, {r1-r7} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */ " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ " msr control, r2 \n"/* Restore the CONTROL register value for the task. */ " bx r3 \n" #else /* configENABLE_MPU */ " adds r0, r0, #24 \n"/* Move to the high registers. */ " ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ " mov r8, r4 \n"/* r8 = r4. */ " mov r9, r5 \n"/* r9 = r5. */ " mov r10, r6 \n"/* r10 = r6. */ " mov r11, r7 \n"/* r11 = r7. */ " 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. */ " 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. */ " bx r3 \n" #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst: .word 0xe000ed94 \n" "xMAIR0Const: .word 0xe000edc0 \n" "xRNRConst: .word 0xe000ed98 \n" "xRBARConst: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } /*-----------------------------------------------------------*/ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " movs r0, #4 \n" " mov r1, lr \n" " tst r0, r1 \n" " beq stacking_used_msp \n" " mrs r0, psp \n" " ldr r2, svchandler_address_const \n" " bx r2 \n" " stacking_used_msp: \n" " mrs r0, msp \n" " ldr r2, svchandler_address_const \n" " bx r2 \n" " \n" " .align 4 \n" "svchandler_address_const: .word vPortSVCHandler_C \n" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M23" #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION * is defined correctly and privileged functions are placed in correct sections. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Portasm includes. */ #include "portasm.h" /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r4, [r2] \n"/* Disable MPU. */ " \n" " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r4, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r4, #4 \n"/* r4 = 4. */ " str r4, [r2] \n"/* Program RNR = 4. */ " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r3!, {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. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r4, #8 \n"/* r4 = 8. */ " str r4, [r2] \n"/* Program RNR = 8. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r3!, {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. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r4, #12 \n"/* r4 = 12. */ " str r4, [r2] \n"/* Program RNR = 12. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r3!, {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. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " str r4, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ " ldr r5, xSecureContextConst2 \n" " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ " msr control, r3 \n"/* Set this task's CONTROL value. */ " 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. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " bx r4 \n"/* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, xSecureContextConst2 \n" " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ " movs r1, #2 \n"/* r1 = 2. */ " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ " 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. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " bx r3 \n"/* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" "xSecureContextConst2: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst2: .word 0xe000ed94 \n" "xMAIR0Const2: .word 0xe000edc0 \n" "xRNRConst2: .word 0xe000ed98 \n" "xRBARConst2: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ " ite ne \n" " 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. */ " bx lr \n"/* Return. */ " \n" " .align 4 \n" ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* Read the CONTROL register. */ " bic r0, #1 \n"/* Clear the bit 0. */ " msr control, r0 \n"/* Write back the new CONTROL value. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vResetPrivilege( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " orr r0, #1 \n"/* r0 = r0 | 1. */ " msr control, r0 \n"/* CONTROL = r0. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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"/* The first entry in vector table is stack pointer. */ " msr msp, r0 \n"/* Set the MSP back to the start of the stack. */ " cpsie i \n"/* Globally enable interrupts. */ " cpsie f \n" " dsb \n" " isb \n" " svc %0 \n"/* System call to start the first task. */ " nop \n" " \n" " .align 4 \n" "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } /*-----------------------------------------------------------*/ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n"/* Return. */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); } /*-----------------------------------------------------------*/ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " msr basepri, r0 \n"/* basepri = ulMask. */ " dsb \n" " isb \n" " bx lr \n"/* Return. */ ::: "memory" ); } /*-----------------------------------------------------------*/ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" " 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 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. */ " mrs r2, psp \n"/* Read PSP in r2. */ " \n" " cbz r0, save_ns_context \n"/* No secure context to save. */ " push {r0-r2, r14} \n" " bl SecureContext_SaveContext \n"/* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r0-r3} \n"/* LR is now in 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. */ " 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" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB.*/ #if ( configENABLE_MPU == 1 ) " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ " str r2, [r1] \n"/* Save the new top of stack in TCB. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r3, control \n"/* r3 = CONTROL. */ " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ " 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. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ " b select_next_task \n" " \n" " save_ns_context: \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ #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. */ " it eq \n" " vstmdbeq r2!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ " str r2, [r1] \n"/* Save the new top of stack in TCB. */ " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r3, control \n"/* r3 = CONTROL. */ " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ " subs r2, r2, #16 \n"/* r2 = r2 - 16. */ " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ " 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. */ " adds r2, r2, #12 \n"/* r2 = r2 + 12. */ " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " subs r2, r2, #12 \n"/* r2 = r2 - 12. */ " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ " \n" " select_next_task: \n" " mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" " mov r0, #0 \n"/* r0 = 0. */ " msr basepri, r0 \n"/* Enable interrupts. */ " \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r4, [r3] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ " str r4, [r3] \n"/* Program MAIR0. */ " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ " movs r4, #4 \n"/* r4 = 4. */ " str r4, [r3] \n"/* Program RNR = 4. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ " movs r4, #8 \n"/* r4 = 8. */ " str r4, [r3] \n"/* Program RNR = 8. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ " movs r4, #12 \n"/* r4 = 12. */ " str r4, [r3] \n"/* Program RNR = 12. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " str r4, [r3] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ " mov lr, r4 \n"/* LR = r4. */ " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( 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. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " push {r2, r4} \n" " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r2, r4} \n" " 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. */ " 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. */ " bx lr \n" #else /* configENABLE_MPU */ " 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. */ " mov lr, r4 \n"/* LR = r4. */ " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( 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. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " push {r2, r4} \n" " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r2, r4} \n" " 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. */ " 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. */ " bx lr \n" #endif /* configENABLE_MPU */ " \n" " restore_ns_context: \n" " ldmia r2!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */ #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. */ " it eq \n" " vldmiaeq r2!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ " msr psp, r2 \n"/* Remember the new top of stack for the task. */ " bx lr \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" "xSecureContextConst: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst: .word 0xe000ed94 \n" "xMAIR0Const: .word 0xe000edc0 \n" "xRNRConst: .word 0xe000ed98 \n" "xRBARConst: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } /*-----------------------------------------------------------*/ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " tst lr, #4 \n" " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" " ldr r1, svchandler_address_const \n" " bx r1 \n" " \n" " .align 4 \n" "svchandler_address_const: .word vPortSVCHandler_C \n" ); } /*-----------------------------------------------------------*/ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " svc %0 \n"/* Secure context is allocated in the supervisor call. */ " bx lr \n"/* Return. */ ::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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. */ " cmp r1, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */ " it ne \n" " svcne %0 \n"/* Secure context is freed in the supervisor call. */ " bx lr \n"/* Return. */ ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M33" #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION * is defined correctly and privileged functions are placed in correct sections. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Portasm includes. */ #include "portasm.h" /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r4, [r2] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r3, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #4 \n"/* r3 = 4. */ " str r3, [r2] \n"/* Program RNR = 4. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #8 \n"/* r3 = 8. */ " str r3, [r2] \n"/* Program RNR = 8. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #12 \n"/* r3 = 12. */ " str r3, [r2] \n"/* Program RNR = 12. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " str r4, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ " msr control, r2 \n"/* Set this task's CONTROL value. */ " 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. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " bx r3 \n"/* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ " movs r1, #2 \n"/* r1 = 2. */ " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ " 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. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " bx r2 \n"/* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst2: .word 0xe000ed94 \n" "xMAIR0Const2: .word 0xe000edc0 \n" "xRNRConst2: .word 0xe000ed98 \n" "xRBARConst2: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ " ite ne \n" " 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. */ " bx lr \n"/* Return. */ " \n" " .align 4 \n" ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* Read the CONTROL register. */ " bic r0, #1 \n"/* Clear the bit 0. */ " msr control, r0 \n"/* Write back the new CONTROL value. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vResetPrivilege( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " orr r0, #1 \n"/* r0 = r0 | 1. */ " msr control, r0 \n"/* CONTROL = r0. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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"/* The first entry in vector table is stack pointer. */ " msr msp, r0 \n"/* Set the MSP back to the start of the stack. */ " cpsie i \n"/* Globally enable interrupts. */ " cpsie f \n" " dsb \n" " isb \n" " svc %0 \n"/* System call to start the first task. */ " nop \n" " \n" " .align 4 \n" "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } /*-----------------------------------------------------------*/ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n"/* Return. */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); } /*-----------------------------------------------------------*/ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " msr basepri, r0 \n"/* basepri = ulMask. */ " dsb \n" " isb \n" " bx lr \n"/* Return. */ ::: "memory" ); } /*-----------------------------------------------------------*/ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, psp \n"/* Read PSP in r0. */ #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. */ " it eq \n" " vstmdbeq r0!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r2, control \n"/* r2 = CONTROL. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r1-r11} \n"/* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ #else /* configENABLE_MPU */ " mrs r2, psplim \n"/* r2 = PSPLIM. */ " 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. */ #endif /* configENABLE_MPU */ " \n" " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " str r0, [r1] \n"/* Save the new top of stack in TCB. */ " \n" " mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" " mov r0, #0 \n"/* r0 = 0. */ " msr basepri, r0 \n"/* Enable interrupts. */ " \n" " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r4, [r2] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r3, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #4 \n"/* r3 = 4. */ " str r3, [r2] \n"/* Program RNR = 4. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #8 \n"/* r3 = 8. */ " str r3, [r2] \n"/* Program RNR = 8. */ " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #12 \n"/* r3 = 12. */ " str r3, [r2] \n"/* Program RNR = 12. */ " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " str r4, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldmia r0!, {r1-r11} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ #else /* configENABLE_MPU */ " ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #endif /* configENABLE_MPU */ " \n" #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. */ " it eq \n" " vldmiaeq r0!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" #if ( configENABLE_MPU == 1 ) " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ " msr control, r2 \n"/* Restore the CONTROL register value for the task. */ #else /* configENABLE_MPU */ " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ #endif /* configENABLE_MPU */ " msr psp, r0 \n"/* Remember the new top of stack for the task. */ " bx r3 \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst: .word 0xe000ed94 \n" "xMAIR0Const: .word 0xe000edc0 \n" "xRNRConst: .word 0xe000ed98 \n" "xRBARConst: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } /*-----------------------------------------------------------*/ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " tst lr, #4 \n" " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" " ldr r1, svchandler_address_const \n" " bx r1 \n" " \n" " .align 4 \n" "svchandler_address_const: .word vPortSVCHandler_C \n" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M33" #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_MVE #error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE. #endif /* configENABLE_MVE */ /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M55" #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_MVE #error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE. #endif /* configENABLE_MVE */ /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M85" #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C EXTERN SecureContext_SaveContext EXTERN SecureContext_LoadContext PUBLIC xIsPrivileged PUBLIC vResetPrivilege PUBLIC vPortAllocateSecureContext PUBLIC vRestoreContextOfFirstTask PUBLIC vRaisePrivilege PUBLIC vStartFirstTask PUBLIC ulSetInterruptMask PUBLIC vClearInterruptMask PUBLIC PendSV_Handler PUBLIC SVC_Handler PUBLIC vPortFreeSecureContext #if ( configENABLE_FPU == 1 ) #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif /*-----------------------------------------------------------*/ /*---------------- Unprivileged Functions -------------------*/ /*-----------------------------------------------------------*/ SECTION .text:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ xIsPrivileged: mrs r0, control /* r0 = CONTROL. */ movs r1, #1 /* r1 = 1. */ tst r0, r1 /* Perform r0 & r1 (bitwise AND) and update the conditions flag. */ beq running_privileged /* If the result of previous AND operation was 0, branch. */ movs r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ bx lr /* Return. */ running_privileged: movs r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ vResetPrivilege: mrs r0, control /* r0 = CONTROL. */ movs r1, #1 /* r1 = 1. */ orrs r0, r1 /* r0 = r0 | r1. */ msr control, r0 /* CONTROL = r0. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vPortAllocateSecureContext: svc 0 /* Secure context is allocated in the supervisor call. portSVC_ALLOCATE_SECURE_CONTEXT = 0. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ /*----------------- Privileged Functions --------------------*/ /*-----------------------------------------------------------*/ SECTION privileged_functions:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ movs r5, #1 /* r5 = 1. */ bics r4, r5 /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ str r4, [r2] /* Disable MPU. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r4, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ movs r5, #4 /* r5 = 4. */ str r5, [r2] /* Program RNR = 4. */ ldmia r3!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */ ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ stmia r4!, {r6,r7} /* Write first set of RBAR/RLAR registers. */ movs r5, #5 /* r5 = 5. */ str r5, [r2] /* Program RNR = 5. */ ldmia r3!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */ ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ stmia r4!, {r6,r7} /* Write second set of RBAR/RLAR registers. */ movs r5, #6 /* r5 = 6. */ str r5, [r2] /* Program RNR = 6. */ ldmia r3!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */ ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ stmia r4!, {r6,r7} /* Write third set of RBAR/RLAR registers. */ movs r5, #7 /* r5 = 7. */ str r5, [r2] /* Program RNR = 7. */ ldmia r3!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */ ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ stmia r4!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ movs r5, #1 /* r5 = 1. */ orrs r4, r5 /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ str r4, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ ldr r5, =xSecureContext str r1, [r5] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ msr control, r3 /* Set this task's CONTROL value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb bx r4 /* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb bx r3 /* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ vRaisePrivilege: mrs r0, control /* Read the CONTROL register. */ movs r1, #1 /* r1 = 1. */ bics r0, r1 /* Clear the bit 0. */ msr control, r0 /* Write back the new CONTROL value. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vStartFirstTask: ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ ldr r0, [r0] /* The first entry in vector table is stack pointer. */ msr msp, r0 /* Set the MSP back to the start of the stack. */ cpsie i /* Globally enable interrupts. */ dsb isb svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ /*-----------------------------------------------------------*/ ulSetInterruptMask: mrs r0, PRIMASK cpsid i bx lr /*-----------------------------------------------------------*/ vClearInterruptMask: msr PRIMASK, r0 bx lr /*-----------------------------------------------------------*/ PendSV_Handler: ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ push {r0-r2, r14} bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r0-r3} /* LR is now in r3. */ mov lr, r3 /* LR = r3. */ lsls r1, r3, #25 /* 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 /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ b select_next_task save_ns_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ adds r2, r2, #16 /* r2 = r2 + 16. */ stmia r2!, {r4-r7} /* Store the low registers that are not saved automatically. */ mov r4, r8 /* r4 = r8. */ mov r5, r9 /* r5 = r9. */ mov r6, r10 /* r6 = r10. */ mov r7, r11 /* r7 = r11. */ stmia r2!, {r4-r7} /* Store the high registers that are not saved automatically. */ mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ subs r2, r2, #48 /* r2 = r2 - 48. */ stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3-r7} /* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ mov r4, r8 /* r4 = r8. */ mov r5, r9 /* r5 = r9. */ mov r6, r10 /* r6 = r10. */ mov r7, r11 /* r7 = r11. */ stmia r2!, {r4-r7} /* Store the high registers that are not saved automatically. */ #endif /* configENABLE_MPU */ select_next_task: cpsid i bl vTaskSwitchContext cpsie i ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r3] /* Read the value of MPU_CTRL. */ movs r5, #1 /* r5 = 1. */ bics r4, r5 /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ str r4, [r3] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ str r4, [r3] /* Program MAIR0. */ ldr r4, =0xe000ed98 /* r4 = 0xe000ed98 [Location of RNR]. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ movs r5, #4 /* r5 = 4. */ str r5, [r4] /* Program RNR = 4. */ ldmia r1!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r6,r7} /* Write first set of RBAR/RLAR registers. */ movs r5, #5 /* r5 = 5. */ str r5, [r4] /* Program RNR = 5. */ ldmia r1!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r6,r7} /* Write second set of RBAR/RLAR registers. */ movs r5, #6 /* r5 = 6. */ str r5, [r4] /* Program RNR = 6. */ ldmia r1!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r6,r7} /* Write third set of RBAR/RLAR registers. */ movs r5, #7 /* r5 = 7. */ str r5, [r4] /* Program RNR = 7. */ ldmia r1!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */ ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r3] /* Read the value of MPU_CTRL. */ movs r5, #1 /* r5 = 1. */ orrs r4, r5 /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ str r4, [r3] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ msr control, r3 /* Restore the CONTROL register value for the task. */ mov lr, r4 /* LR = r4. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ push {r2, r4} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r2, r4} mov lr, r4 /* LR = r4. */ lsls r1, r4, #25 /* 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 /* 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 /* Remember the new top of stack for the task. */ bx lr #else /* configENABLE_MPU */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ push {r2, r4} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r2, r4} mov lr, r4 /* LR = r4. */ lsls r1, r4, #25 /* 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 /* 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 /* Remember the new top of stack for the task. */ bx lr #endif /* configENABLE_MPU */ restore_ns_context: adds r2, r2, #16 /* Move to the high registers. */ ldmia r2!, {r4-r7} /* Restore the high registers that are not automatically restored. */ mov r8, r4 /* r8 = r4. */ mov r9, r5 /* r9 = r5. */ mov r10, r6 /* r10 = r6. */ mov r11, r7 /* r11 = r7. */ msr psp, r2 /* Remember the new top of stack for the task. */ subs r2, r2, #32 /* Go back to the low registers. */ ldmia r2!, {r4-r7} /* Restore the low registers that are not automatically restored. */ bx lr /*-----------------------------------------------------------*/ SVC_Handler: movs r0, #4 mov r1, lr tst r0, r1 beq stacking_used_msp mrs r0, psp b vPortSVCHandler_C stacking_used_msp: mrs r0, msp b vPortSVCHandler_C /*-----------------------------------------------------------*/ vPortFreeSecureContext: ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ bne free_secure_context /* Branch if r1 != 0. */ bx lr /* There is no secure context (xSecureContext is NULL). */ free_secure_context: svc 1 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 1. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M23" #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Be006 #pragma diag_suppress=Pa082 /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portasm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" EXTERN pxCurrentTCB EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C PUBLIC xIsPrivileged PUBLIC vResetPrivilege PUBLIC vRestoreContextOfFirstTask PUBLIC vRaisePrivilege PUBLIC vStartFirstTask PUBLIC ulSetInterruptMask PUBLIC vClearInterruptMask PUBLIC PendSV_Handler PUBLIC SVC_Handler #if ( configENABLE_FPU == 1 ) #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif /*-----------------------------------------------------------*/ /*---------------- Unprivileged Functions -------------------*/ /*-----------------------------------------------------------*/ SECTION .text:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ xIsPrivileged: mrs r0, control /* r0 = CONTROL. */ movs r1, #1 /* r1 = 1. */ tst r0, r1 /* Perform r0 & r1 (bitwise AND) and update the conditions flag. */ beq running_privileged /* If the result of previous AND operation was 0, branch. */ movs r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ bx lr /* Return. */ running_privileged: movs r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ vResetPrivilege: mrs r0, control /* r0 = CONTROL. */ movs r1, #1 /* r1 = 1. */ orrs r0, r1 /* r0 = r0 | r1. */ msr control, r0 /* CONTROL = r0. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ /*----------------- Privileged Functions --------------------*/ /*-----------------------------------------------------------*/ SECTION privileged_functions:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r3, [r2] /* Read the value of MPU_CTRL. */ movs r4, #1 /* r4 = 1. */ bics r3, r4 /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ str r3, [r2] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r4, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ movs r4, #4 /* r4 = 4. */ str r4, [r2] /* Program RNR = 4. */ ldmia r1!, {r5,r6} /* Read first set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r5,r6} /* Write first set of RBAR/RLAR registers. */ movs r4, #5 /* r4 = 5. */ str r4, [r2] /* Program RNR = 5. */ ldmia r1!, {r5,r6} /* Read second set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r5,r6} /* Write second set of RBAR/RLAR registers. */ movs r4, #6 /* r4 = 6. */ str r4, [r2] /* Program RNR = 6. */ ldmia r1!, {r5,r6} /* Read third set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r5,r6} /* Write third set of RBAR/RLAR registers. */ movs r4, #7 /* r4 = 7. */ str r4, [r2] /* Program RNR = 7. */ ldmia r1!, {r5,r6} /* Read fourth set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r5,r6} /* Write fourth set of RBAR/RLAR registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r3, [r2] /* Read the value of MPU_CTRL. */ movs r4, #1 /* r4 = 1. */ orrs r3, r4 /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ str r3, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ msr control, r2 /* Set this task's CONTROL value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb bx r3 /* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb bx r2 /* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ vRaisePrivilege: mrs r0, control /* Read the CONTROL register. */ movs r1, #1 /* r1 = 1. */ bics r0, r1 /* Clear the bit 0. */ msr control, r0 /* Write back the new CONTROL value. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vStartFirstTask: ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ ldr r0, [r0] /* The first entry in vector table is stack pointer. */ msr msp, r0 /* Set the MSP back to the start of the stack. */ cpsie i /* Globally enable interrupts. */ dsb isb svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ nop /*-----------------------------------------------------------*/ ulSetInterruptMask: mrs r0, PRIMASK cpsid i bx lr /*-----------------------------------------------------------*/ vClearInterruptMask: msr PRIMASK, r0 bx lr /*-----------------------------------------------------------*/ PendSV_Handler: mrs r0, psp /* Read PSP in r0. */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) subs r0, r0, #44 /* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */ str r0, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mrs r2, control /* r2 = CONTROL. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r0!, {r1-r7} /* Store on the stack - PSPLIM, CONTROL, LR and low registers that are not automatically saved. */ mov r4, r8 /* r4 = r8. */ mov r5, r9 /* r5 = r9. */ mov r6, r10 /* r6 = r10. */ mov r7, r11 /* r7 = r11. */ stmia r0!, {r4-r7} /* Store the high registers that are not saved automatically. */ #else /* configENABLE_MPU */ subs r0, r0, #40 /* Make space for PSPLIM, LR and the remaining registers on the stack. */ str r0, [r1] /* Save the new top of stack in TCB. */ mrs r2, psplim /* r2 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r0!, {r2-r7} /* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */ mov r4, r8 /* r4 = r8. */ mov r5, r9 /* r5 = r9. */ mov r6, r10 /* r6 = r10. */ mov r7, r11 /* r7 = r11. */ stmia r0!, {r4-r7} /* Store the high registers that are not saved automatically. */ #endif /* configENABLE_MPU */ cpsid i bl vTaskSwitchContext cpsie i ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r3, [r2] /* Read the value of MPU_CTRL. */ movs r4, #1 /* r4 = 1. */ bics r3, r4 /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ str r3, [r2] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r4, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ movs r4, #4 /* r4 = 4. */ str r4, [r2] /* Program RNR = 4. */ ldmia r1!, {r5,r6} /* Read first set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r5,r6} /* Write first set of RBAR/RLAR registers. */ movs r4, #5 /* r4 = 5. */ str r4, [r2] /* Program RNR = 5. */ ldmia r1!, {r5,r6} /* Read second set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r5,r6} /* Write second set of RBAR/RLAR registers. */ movs r4, #6 /* r4 = 6. */ str r4, [r2] /* Program RNR = 6. */ ldmia r1!, {r5,r6} /* Read third set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r5,r6} /* Write third set of RBAR/RLAR registers. */ movs r4, #7 /* r4 = 7. */ str r4, [r2] /* Program RNR = 7. */ ldmia r1!, {r5,r6} /* Read fourth set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r5,r6} /* Write fourth set of RBAR/RLAR registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r3, [r2] /* Read the value of MPU_CTRL. */ movs r4, #1 /* r4 = 1. */ orrs r3, r4 /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ str r3, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) adds r0, r0, #28 /* Move to the high registers. */ ldmia r0!, {r4-r7} /* Restore the high registers that are not automatically restored. */ mov r8, r4 /* r8 = r4. */ mov r9, r5 /* r9 = r5. */ mov r10, r6 /* r10 = r6. */ mov r11, r7 /* r11 = r7. */ msr psp, r0 /* Remember the new top of stack for the task. */ subs r0, r0, #44 /* Move to the starting of the saved context. */ ldmia r0!, {r1-r7} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ msr control, r2 /* Restore the CONTROL register value for the task. */ bx r3 #else /* configENABLE_MPU */ adds r0, r0, #24 /* Move to the high registers. */ ldmia r0!, {r4-r7} /* Restore the high registers that are not automatically restored. */ mov r8, r4 /* r8 = r4. */ mov r9, r5 /* r9 = r5. */ mov r10, r6 /* r10 = r6. */ mov r11, r7 /* r11 = r7. */ msr psp, r0 /* Remember the new top of stack for the task. */ subs r0, r0, #40 /* Move to the starting of the saved context. */ ldmia r0!, {r2-r7} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */ bx r3 #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ SVC_Handler: movs r0, #4 mov r1, lr tst r0, r1 beq stacking_used_msp mrs r0, psp b vPortSVCHandler_C stacking_used_msp: mrs r0, msp b vPortSVCHandler_C /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M23" #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Be006 #pragma diag_suppress=Pa082 /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C EXTERN SecureContext_SaveContext EXTERN SecureContext_LoadContext PUBLIC xIsPrivileged PUBLIC vResetPrivilege PUBLIC vPortAllocateSecureContext PUBLIC vRestoreContextOfFirstTask PUBLIC vRaisePrivilege PUBLIC vStartFirstTask PUBLIC ulSetInterruptMask PUBLIC vClearInterruptMask PUBLIC PendSV_Handler PUBLIC SVC_Handler PUBLIC vPortFreeSecureContext /*-----------------------------------------------------------*/ /*---------------- Unprivileged Functions -------------------*/ /*-----------------------------------------------------------*/ SECTION .text:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ xIsPrivileged: mrs r0, control /* r0 = CONTROL. */ tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ ite ne movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ vResetPrivilege: mrs r0, control /* r0 = CONTROL. */ orr r0, r0, #1 /* r0 = r0 | 1. */ msr control, r0 /* CONTROL = r0. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vPortAllocateSecureContext: svc 0 /* Secure context is allocated in the supervisor call. portSVC_ALLOCATE_SECURE_CONTEXT = 0. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ /*----------------- Privileged Functions --------------------*/ /*-----------------------------------------------------------*/ SECTION privileged_functions:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ str r4, [r2] /* Disable MPU. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r4, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ movs r4, #4 /* r4 = 4. */ str r4, [r2] /* Program RNR = 4. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldmia r3!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ str r4, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ ldr r5, =xSecureContext str r1, [r5] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ msr control, r3 /* Set this task's CONTROL value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r4 /* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r3 /* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ vRaisePrivilege: mrs r0, control /* Read the CONTROL register. */ bic r0, r0, #1 /* Clear the bit 0. */ msr control, r0 /* Write back the new CONTROL value. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vStartFirstTask: ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ ldr r0, [r0] /* The first entry in vector table is stack pointer. */ msr msp, r0 /* Set the MSP back to the start of the stack. */ cpsie i /* Globally enable interrupts. */ cpsie f dsb isb svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ /*-----------------------------------------------------------*/ ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ /*-----------------------------------------------------------*/ vClearInterruptMask: msr basepri, r0 /* basepri = ulMask. */ dsb isb bx lr /* Return. */ /*-----------------------------------------------------------*/ PendSV_Handler: ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ push {r0-r2, r14} bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r0-r3} /* LR is now in r3. */ mov lr, r3 /* LR = r3. */ lsls r1, r3, #25 /* 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 /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ b select_next_task save_ns_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ adds r2, r2, #16 /* r2 = r2 + 16. */ stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ subs r2, r2, #16 /* r2 = r2 - 16. */ stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ adds r2, r2, #12 /* r2 = r2 + 12. */ stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ subs r2, r2, #12 /* r2 = r2 - 12. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r3] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ str r4, [r3] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ str r4, [r3] /* Program MAIR0. */ ldr r3, =0xe000ed98 /* r3 = 0xe000ed98 [Location of RNR]. */ movs r4, #4 /* r4 = 4. */ str r4, [r3] /* Program RNR = 4. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ stmia r3!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r3] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ str r4, [r3] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ msr control, r3 /* Restore the CONTROL register value for the task. */ mov lr, r4 /* LR = r4. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ push {r2, r4} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r2, r4} mov lr, r4 /* LR = r4. */ lsls r1, r4, #25 /* 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 /* 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 /* Remember the new top of stack for the task. */ bx lr #else /* configENABLE_MPU */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ push {r2, r4} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r2, r4} mov lr, r4 /* LR = r4. */ lsls r1, r4, #25 /* 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 /* 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 /* Remember the new top of stack for the task. */ bx lr #endif /* configENABLE_MPU */ restore_ns_context: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ msr psp, r2 /* Remember the new top of stack for the task. */ bx lr /*-----------------------------------------------------------*/ SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp b vPortSVCHandler_C /*-----------------------------------------------------------*/ vPortFreeSecureContext: /* r0 = uint32_t *pulTCB. */ ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ it ne svcne 1 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 1. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M33" #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Be006 #pragma diag_suppress=Pa082 /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portasm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" EXTERN pxCurrentTCB EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C PUBLIC xIsPrivileged PUBLIC vResetPrivilege PUBLIC vRestoreContextOfFirstTask PUBLIC vRaisePrivilege PUBLIC vStartFirstTask PUBLIC ulSetInterruptMask PUBLIC vClearInterruptMask PUBLIC PendSV_Handler PUBLIC SVC_Handler /*-----------------------------------------------------------*/ /*---------------- Unprivileged Functions -------------------*/ /*-----------------------------------------------------------*/ SECTION .text:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ xIsPrivileged: mrs r0, control /* r0 = CONTROL. */ tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ ite ne movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ vResetPrivilege: mrs r0, control /* r0 = CONTROL. */ orr r0, r0, #1 /* r0 = r0 | 1. */ msr control, r0 /* CONTROL = r0. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ /*----------------- Privileged Functions --------------------*/ /*-----------------------------------------------------------*/ SECTION privileged_functions:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ str r4, [r2] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r3, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ movs r3, #4 /* r3 = 4. */ str r3, [r2] /* Program RNR = 4. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ str r4, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ msr control, r2 /* Set this task's CONTROL value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r3 /* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r2 /* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ vRaisePrivilege: mrs r0, control /* Read the CONTROL register. */ bic r0, r0, #1 /* Clear the bit 0. */ msr control, r0 /* Write back the new CONTROL value. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vStartFirstTask: ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ ldr r0, [r0] /* The first entry in vector table is stack pointer. */ msr msp, r0 /* Set the MSP back to the start of the stack. */ cpsie i /* Globally enable interrupts. */ cpsie f dsb isb svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ /*-----------------------------------------------------------*/ ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ /*-----------------------------------------------------------*/ vClearInterruptMask: msr basepri, r0 /* basepri = ulMask. */ dsb isb bx lr /* Return. */ /*-----------------------------------------------------------*/ PendSV_Handler: mrs r0, psp /* Read PSP in r0. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r0!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) mrs r1, psplim /* r1 = PSPLIM. */ mrs r2, control /* r2 = CONTROL. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r1-r11} /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ #else /* configENABLE_MPU */ mrs r2, psplim /* r2 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ #endif /* configENABLE_MPU */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ str r4, [r2] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r3, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ movs r3, #4 /* r3 = 4. */ str r3, [r2] /* Program RNR = 4. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ str r4, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldmia r0!, {r1-r11} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ #else /* configENABLE_MPU */ ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #endif /* configENABLE_MPU */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst r3, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r0!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) msr psplim, r1 /* Restore the PSPLIM register value for the task. */ msr control, r2 /* Restore the CONTROL register value for the task. */ #else /* configENABLE_MPU */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */ #endif /* configENABLE_MPU */ msr psp, r0 /* Remember the new top of stack for the task. */ bx r3 /*-----------------------------------------------------------*/ SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp b vPortSVCHandler_C /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M33" #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Be006 #pragma diag_suppress=Pa082 /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/IAR/ARM_CM55/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_MVE #error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE. #endif /* configENABLE_MVE */ /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M55" #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Be006 #pragma diag_suppress=Pa082 /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portable/IAR/ARM_CM85/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_MVE #error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE. #endif /* configENABLE_MVE */ /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M85" #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Be006 #pragma diag_suppress=Pa082 /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORT_ASM_H__ #define __PORT_ASM_H__ /* Scheduler includes. */ #include "FreeRTOS.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /** * @brief Restore the context of the first task so that the first task starts * executing. */ void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * * @note This is a privileged function and should only be called from the kenrel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Starts the first task. */ void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Disables interrupts. */ uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Enables interrupts. */ void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief PendSV Exception handler. */ void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief SVC Handler. */ void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Allocate a Secure context for the calling task. * * @param[in] ulSecureStackSize The size of the stack to be allocated on the * secure side for the calling task. */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); /** * @brief Free the task's secure context. * * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. */ void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* __PORT_ASM_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/non_secure/portmacrocommon.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACROCOMMON_H #define PORTMACROCOMMON_H #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_FPU #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. #endif /* configENABLE_FPU */ #ifndef configENABLE_MPU #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. #endif /* configENABLE_MPU */ #ifndef configENABLE_TRUSTZONE #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ /** * @brief Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif #define portHAS_STACK_OVERFLOW_CHECKING 1 /*-----------------------------------------------------------*/ /** * @brief Extern declarations. */ extern BaseType_t xPortIsInsideInterrupt( void ); extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; #if ( configENABLE_TRUSTZONE == 1 ) extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_MPU == 1 ) extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief MPU specific constants. */ #if ( configENABLE_MPU == 1 ) #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #else #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* MPU regions. */ #define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_RAM_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ /* Device memory attributes used in MPU_MAIR registers. * * 8-bit values encoded as follows: * Bit[7:4] - 0000 - Device Memory * Bit[3:2] - 00 --> Device-nGnRnE * 01 --> Device-nGnRE * 10 --> Device-nGRE * 11 --> Device-GRE * Bit[1:0] - 00, Reserved. */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ /* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ /* Attributes used in MPU_RBAR registers. */ #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ /** * @brief Settings to define an MPU region. */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */ } MPURegionSettings_t; /** * @brief MPU settings as stored in the TCB. */ typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ } xMPU_SETTINGS; /*-----------------------------------------------------------*/ /** * @brief SVC numbers. */ #define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 /*-----------------------------------------------------------*/ /** * @brief Scheduler utilities. */ #define portYIELD() vPortYield() #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /** * @brief Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /** * @brief Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Allocate a secure context for the task. * * 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 context before it calls any secure function. * * @param[in] ulSecureStackSize The size of the secure stack to be allocated. */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) /** * @brief Called when a task is deleted to delete the task's secure context, * if it has one. * * @param[in] pxTCB The TCB of the task being deleted. */ #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. * * 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, * the privilege is not raised. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() #else #define portIS_PRIVILEGED() #define portRAISE_PRIVILEGE() #define portRESET_PRIVILEGE() #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief Barriers. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACROCOMMON_H */ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/secure/ReadMe.txt ================================================ This directory tree contains the master copy of the FreeRTOS Armv8-M and Armv8.1-M ports. 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 release. If your Armv8-M/Armv8.1-M application uses TrustZone then use the files from the FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85] directories. If your Armv8-M/Armv8.1-M application does not use TrustZone then use the files from the FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85]_NTZ directories. ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/secure/context/portable/GCC/ARM_CM23/secure_context_port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Secure context includes. */ #include "secure_context.h" /* Secure port macros. */ #include "secure_port_macros.h" #if ( configENABLE_FPU == 1 ) #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) { /* pxSecureContext value is in r0. */ __asm volatile ( " .syntax unified \n" " \n" " mrs r1, ipsr \n" /* r1 = IPSR. */ " cbz r1, load_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */ " ldmia r0!, {r1, r2} \n" /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */ " \n" #if ( configENABLE_MPU == 1 ) " ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */ " msr control, r3 \n" /* CONTROL = r3. */ #endif /* configENABLE_MPU */ " \n" " msr psplim, r2 \n" /* PSPLIM = r2. */ " msr psp, r1 \n" /* PSP = r1. */ " \n" " load_ctx_therad_mode: \n" " bx lr \n" " \n" ::: "r0", "r1", "r2" ); } /*-----------------------------------------------------------*/ void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) { /* pxSecureContext value is in r0. */ __asm volatile ( " .syntax unified \n" " \n" " mrs r1, ipsr \n" /* r1 = IPSR. */ " cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */ " mrs r1, psp \n" /* r1 = PSP. */ " \n" #if ( configENABLE_MPU == 1 ) " mrs r2, control \n" /* r2 = CONTROL. */ " subs r1, r1, #4 \n" /* Make space for the CONTROL value on the stack. */ " str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ " stmia r1!, {r2} \n" /* Store CONTROL value on the stack. */ #else /* configENABLE_MPU */ " str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ #endif /* configENABLE_MPU */ " \n" " movs r1, %0 \n" /* r1 = securecontextNO_STACK. */ " msr psplim, r1 \n" /* PSPLIM = securecontextNO_STACK. */ " msr psp, r1 \n" /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */ " \n" " save_ctx_therad_mode: \n" " bx lr \n" " \n" ::"i" ( securecontextNO_STACK ) : "r1", "memory" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/secure/context/portable/GCC/ARM_CM33/secure_context_port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Secure context includes. */ #include "secure_context.h" /* Secure port macros. */ #include "secure_port_macros.h" void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) { /* pxSecureContext value is in r0. */ __asm volatile ( " .syntax unified \n" " \n" " mrs r1, ipsr \n" /* r1 = IPSR. */ " cbz r1, load_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */ " ldmia r0!, {r1, r2} \n" /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */ " \n" #if ( configENABLE_MPU == 1 ) " ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */ " msr control, r3 \n" /* CONTROL = r3. */ #endif /* configENABLE_MPU */ " \n" " msr psplim, r2 \n" /* PSPLIM = r2. */ " msr psp, r1 \n" /* PSP = r1. */ " \n" " load_ctx_therad_mode: \n" " bx lr \n" " \n" ::: "r0", "r1", "r2" ); } /*-----------------------------------------------------------*/ void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) { /* pxSecureContext value is in r0. */ __asm volatile ( " .syntax unified \n" " \n" " mrs r1, ipsr \n" /* r1 = IPSR. */ " cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */ " mrs r1, psp \n" /* r1 = PSP. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " vstmdb r1!, {s0} \n" /* Trigger the deferred stacking of FPU registers. */ " vldmia r1!, {s0} \n" /* Nullify the effect of the previous statement. */ #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" #if ( configENABLE_MPU == 1 ) " mrs r2, control \n" /* r2 = CONTROL. */ " stmdb r1!, {r2} \n" /* Store CONTROL value on the stack. */ #endif /* configENABLE_MPU */ " \n" " str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ " movs r1, %0 \n" /* r1 = securecontextNO_STACK. */ " msr psplim, r1 \n" /* PSPLIM = securecontextNO_STACK. */ " msr psp, r1 \n" /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */ " \n" " save_ctx_therad_mode: \n" " bx lr \n" " \n" ::"i" ( securecontextNO_STACK ) : "r1", "memory" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/secure/context/portable/IAR/ARM_CM23/secure_context_port_asm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ SECTION .text:CODE:NOROOT(2) THUMB /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" PUBLIC SecureContext_LoadContextAsm PUBLIC SecureContext_SaveContextAsm #if ( configENABLE_FPU == 1 ) #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif /*-----------------------------------------------------------*/ SecureContext_LoadContextAsm: /* pxSecureContext value is in r0. */ mrs r1, ipsr /* r1 = IPSR. */ cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ ldmia r0!, {r1, r2} /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */ #if ( configENABLE_MPU == 1 ) ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */ msr control, r3 /* CONTROL = r3. */ #endif /* configENABLE_MPU */ msr psplim, r2 /* PSPLIM = r2. */ msr psp, r1 /* PSP = r1. */ load_ctx_therad_mode: bx lr /*-----------------------------------------------------------*/ SecureContext_SaveContextAsm: /* pxSecureContext value is in r0. */ mrs r1, ipsr /* r1 = IPSR. */ cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ mrs r1, psp /* r1 = PSP. */ #if ( configENABLE_MPU == 1 ) mrs r2, control /* r2 = CONTROL. */ subs r1, r1, #4 /* Make space for the CONTROL value on the stack. */ str r1, [r0] /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ stmia r1!, {r2} /* Store CONTROL value on the stack. */ #else /* configENABLE_MPU */ str r1, [r0] /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ #endif /* configENABLE_MPU */ movs r1, #0 /* r1 = securecontextNO_STACK. */ msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */ msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */ save_ctx_therad_mode: bx lr /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/secure/context/portable/IAR/ARM_CM33/secure_context_port_asm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ SECTION .text:CODE:NOROOT(2) THUMB /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" PUBLIC SecureContext_LoadContextAsm PUBLIC SecureContext_SaveContextAsm /*-----------------------------------------------------------*/ SecureContext_LoadContextAsm: /* pxSecureContext value is in r0. */ mrs r1, ipsr /* r1 = IPSR. */ cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ ldmia r0!, {r1, r2} /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */ #if ( configENABLE_MPU == 1 ) ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */ msr control, r3 /* CONTROL = r3. */ #endif /* configENABLE_MPU */ msr psplim, r2 /* PSPLIM = r2. */ msr psp, r1 /* PSP = r1. */ load_ctx_therad_mode: bx lr /*-----------------------------------------------------------*/ SecureContext_SaveContextAsm: /* pxSecureContext value is in r0. */ mrs r1, ipsr /* r1 = IPSR. */ cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ mrs r1, psp /* r1 = PSP. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) vstmdb r1!, {s0} /* Trigger the deferred stacking of FPU registers. */ vldmia r1!, {s0} /* Nullify the effect of the previous statement. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) mrs r2, control /* r2 = CONTROL. */ stmdb r1!, {r2} /* Store CONTROL value on the stack. */ #endif /* configENABLE_MPU */ str r1, [r0] /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ movs r1, #0 /* r1 = securecontextNO_STACK. */ msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */ msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */ save_ctx_therad_mode: bx lr /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/secure/context/secure_context.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Secure context includes. */ #include "secure_context.h" /* Secure heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief CONTROL value for privileged tasks. * * Bit[0] - 0 --> Thread mode is privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_PRIVILEGED 0x02 /** * @brief CONTROL value for un-privileged tasks. * * Bit[0] - 1 --> Thread mode is un-privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 /** * @brief Size of stack seal values in bytes. */ #define securecontextSTACK_SEAL_SIZE 8 /** * @brief Stack seal value as recommended by ARM. */ #define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5 /** * @brief Maximum number of secure contexts. */ #ifndef secureconfigMAX_SECURE_CONTEXTS #define secureconfigMAX_SECURE_CONTEXTS 8UL #endif /*-----------------------------------------------------------*/ /** * @brief Pre-allocated array of secure contexts. */ SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ]; /*-----------------------------------------------------------*/ /** * @brief Get a free secure context for a task from the secure context pool (xSecureContexts). * * This function ensures that only one secure context is allocated for a task. * * @param[in] pvTaskHandle The task handle for which the secure context is allocated. * * @return Index of a free secure context in the xSecureContexts array. */ static uint32_t ulGetSecureContext( void * pvTaskHandle ); /** * @brief Return the secure context to the secure context pool (xSecureContexts). * * @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array. */ static void vReturnSecureContext( uint32_t ulSecureContextIndex ); /* These are implemented in assembly. */ extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ); extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ); /*-----------------------------------------------------------*/ static uint32_t ulGetSecureContext( void * pvTaskHandle ) { /* Start with invalid index. */ uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) && ( xSecureContexts[ i ].pucStackLimit == NULL ) && ( xSecureContexts[ i ].pucStackStart == NULL ) && ( xSecureContexts[ i ].pvTaskHandle == NULL ) && ( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = i; } else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle ) { /* A task can only have one secure context. Do not allocate a second * context for the same task. */ ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; break; } } return ulSecureContextIndex; } /*-----------------------------------------------------------*/ static void vReturnSecureContext( uint32_t ulSecureContextIndex ) { xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) { uint32_t ulIPSR, i; static uint32_t ulSecureContextsInitialized = 0; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) ) { /* Ensure to initialize secure contexts only once. */ ulSecureContextsInitialized = 1; /* No stack for thread mode until a task's context is loaded. */ secureportSET_PSPLIM( securecontextNO_STACK ); secureportSET_PSP( securecontextNO_STACK ); /* Initialize all secure contexts. */ for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { xSecureContexts[ i ].pucCurrentStackPointer = NULL; xSecureContexts[ i ].pucStackLimit = NULL; xSecureContexts[ i ].pucStackStart = NULL; xSecureContexts[ i ].pvTaskHandle = NULL; } #if ( configENABLE_MPU == 1 ) { /* Configure thread mode to use PSP and to be unprivileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED ); } #else /* configENABLE_MPU */ { /* Configure thread mode to use PSP and to be privileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED ); } #endif /* configENABLE_MPU */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ) #else /* configENABLE_MPU */ secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ) #endif /* configENABLE_MPU */ { uint8_t * pucStackMemory = NULL; uint8_t * pucStackLimit; uint32_t ulIPSR, ulSecureContextIndex; SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID; #if ( configENABLE_MPU == 1 ) uint32_t * pulCurrentStackPointer = NULL; #endif /* configENABLE_MPU */ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit * Register (PSPLIM) value. */ secureportREAD_IPSR( ulIPSR ); secureportREAD_PSPLIM( pucStackLimit ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. * Also do nothing, if a secure context us already loaded. PSPLIM is set to * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { /* Ontain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space. */ pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE ); if( pucStackMemory != NULL ) { /* Since stack grows down, the starting point will be the last * location. Note that this location is next to the last * allocated byte for stack (excluding the space for seal values) * because the hardware decrements the stack pointer before * writing i.e. if stack pointer is 0x2, a push operation will * decrement the stack pointer to 0x1 and then write at 0x1. */ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize; /* Seal the created secure process stack. */ *( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE; *( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE; /* The stack cannot go beyond this location. This value is * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle; #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 ) { *( 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 /* configENABLE_MPU */ { /* Current SP is set to the starting of the stack. This * value programmed in the PSP register on context switch. */ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart; } #endif /* configENABLE_MPU */ /* Ensure to never return 0 as a valid context handle. */ xSecureContextHandle = ulSecureContextIndex + 1UL; } } } return xSecureContextHandle; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint32_t ulIPSR, ulSecureContextIndex; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* Only free if a valid context handle is passed. */ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; /* Ensure that the secure context being deleted is associated with * the task. */ if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) { /* Free the stack space. */ vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); /* Return the secure context back to the free secure contexts pool. */ vReturnSecureContext( ulSecureContextIndex ); } } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that no secure context is loaded and the task is loading it's * own context. */ if( ( pucStackLimit == securecontextNO_STACK ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that task's context is loaded and the task is saving it's own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/secure/context/secure_context.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_CONTEXT_H__ #define __SECURE_CONTEXT_H__ /* Standard includes. */ #include /* FreeRTOS includes. */ #include "FreeRTOSConfig.h" /** * @brief PSP value when no secure context is loaded. */ #define securecontextNO_STACK 0x0 /** * @brief Invalid context ID. */ #define securecontextINVALID_CONTEXT_ID 0UL /*-----------------------------------------------------------*/ /** * @brief Structure to represent a secure context. * * @note Since stack grows down, pucStackStart is the highest address while * pucStackLimit is the first address of the allocated memory. */ typedef struct SecureContext { uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */ uint8_t * pucStackStart; /**< First location of the stack memory. */ void * pvTaskHandle; /**< Task handle of the task this context is associated with. */ } SecureContext_t; /*-----------------------------------------------------------*/ /** * @brief Opaque handle for a secure context. */ typedef uint32_t SecureContextHandle_t; /*-----------------------------------------------------------*/ /** * @brief Initializes the secure context management system. * * PSP is set to NULL and therefore a task must allocate and load a context * before calling any secure side function in the thread mode. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureContext_Init( void ); /** * @brief Allocates a context on the secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] ulSecureStackSize Size of the stack to allocate on secure side. * @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise. * * @return Opaque context handle if context is successfully allocated, NULL * otherwise. */ #if ( configENABLE_MPU == 1 ) SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ); #else /* configENABLE_MPU */ SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ); #endif /* configENABLE_MPU */ /** * @brief Frees the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the * context to be freed. */ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Loads the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be loaded. */ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Saves the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be saved. */ void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); #endif /* __SECURE_CONTEXT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/secure/heap/secure_heap.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure context heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Total heap size. */ #ifndef secureconfigTOTAL_HEAP_SIZE #define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) ) #endif /* No test marker by default. */ #ifndef mtCOVERAGE_TEST_MARKER #define mtCOVERAGE_TEST_MARKER() #endif /* No tracing by default. */ #ifndef traceMALLOC #define traceMALLOC( pvReturn, xWantedSize ) #endif /* No tracing by default. */ #ifndef traceFREE #define traceFREE( pv, xBlockSize ) #endif /* Block sizes must not get too small. */ #define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) /* Assumes 8bit bytes! */ #define secureheapBITS_PER_BYTE ( ( size_t ) 8 ) /*-----------------------------------------------------------*/ /* Allocate the memory for the heap. */ #if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) /* The application writer has already defined the array used for the RTOS * heap - probably so it can be placed in a special segment or address. */ extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #else /* configAPPLICATION_ALLOCATED_HEAP */ static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #endif /* configAPPLICATION_ALLOCATED_HEAP */ /** * @brief The linked list structure. * * This is used to link free blocks in order of their memory address. */ typedef struct A_BLOCK_LINK { struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */ size_t xBlockSize; /**< The size of the free block. */ } BlockLink_t; /*-----------------------------------------------------------*/ /** * @brief Called automatically to setup the required heap structures the first * time pvPortMalloc() is called. */ static void prvHeapInit( void ); /** * @brief Inserts a block of memory that is being freed into the correct * position in the list of free memory blocks. * * The block being freed will be merged with the block in front it and/or the * block behind it if the memory blocks are adjacent to each other. * * @param[in] pxBlockToInsert The block being freed. */ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ); /*-----------------------------------------------------------*/ /** * @brief The size of the structure placed at the beginning of each allocated * memory block must by correctly byte aligned. */ static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); /** * @brief Create a couple of list links to mark the start and end of the list. */ static BlockLink_t xStart; static BlockLink_t * pxEnd = NULL; /** * @brief Keeps track of the number of free bytes remaining, but says nothing * about fragmentation. */ static size_t xFreeBytesRemaining = 0U; static size_t xMinimumEverFreeBytesRemaining = 0U; /** * @brief Gets set to the top bit of an size_t type. * * When this bit in the xBlockSize member of an BlockLink_t structure is set * then the block belongs to the application. When the bit is free the block is * still part of the free heap space. */ static size_t xBlockAllocatedBit = 0; /*-----------------------------------------------------------*/ static void prvHeapInit( void ) { BlockLink_t * pxFirstFreeBlock; uint8_t * pucAlignedHeap; size_t uxAddress; size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE; /* Ensure the heap starts on a correctly aligned boundary. */ uxAddress = ( size_t ) ucHeap; if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 ) { uxAddress += ( secureportBYTE_ALIGNMENT - 1 ); uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; } pucAlignedHeap = ( uint8_t * ) uxAddress; /* xStart is used to hold a pointer to the first item in the list of free * blocks. The void cast is used to prevent compiler warnings. */ xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; xStart.xBlockSize = ( size_t ) 0; /* pxEnd is used to mark the end of the list of free blocks and is inserted * at the end of the heap space. */ uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; uxAddress -= xHeapStructSize; uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); pxEnd = ( void * ) uxAddress; pxEnd->xBlockSize = 0; pxEnd->pxNextFreeBlock = NULL; /* To start with there is a single free block that is sized to take up the * entire heap space, minus the space taken by pxEnd. */ pxFirstFreeBlock = ( void * ) pucAlignedHeap; pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; pxFirstFreeBlock->pxNextFreeBlock = pxEnd; /* Only one block exists - and it covers the entire usable heap space. */ xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; /* Work out the position of the top bit in a size_t variable. */ xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 ); } /*-----------------------------------------------------------*/ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) { BlockLink_t * pxIterator; uint8_t * puc; /* Iterate through the list until a block is found that has a higher address * than the block being inserted. */ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) { /* Nothing to do here, just iterate to the right position. */ } /* Do the block being inserted, and the block it is being inserted after * make a contiguous block of memory? */ puc = ( uint8_t * ) pxIterator; if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) { pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; pxBlockToInsert = pxIterator; } else { mtCOVERAGE_TEST_MARKER(); } /* Do the block being inserted, and the block it is being inserted before * make a contiguous block of memory? */ puc = ( uint8_t * ) pxBlockToInsert; if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) { if( pxIterator->pxNextFreeBlock != pxEnd ) { /* Form one big block from the two blocks. */ pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; } else { pxBlockToInsert->pxNextFreeBlock = pxEnd; } } else { pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } /* If the block being inserted plugged a gab, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ if( pxIterator != pxBlockToInsert ) { pxIterator->pxNextFreeBlock = pxBlockToInsert; } else { mtCOVERAGE_TEST_MARKER(); } } /*-----------------------------------------------------------*/ void * pvPortMalloc( size_t xWantedSize ) { BlockLink_t * pxBlock; BlockLink_t * pxPreviousBlock; BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ if( pxEnd == NULL ) { prvHeapInit(); } else { mtCOVERAGE_TEST_MARKER(); } /* Check the requested block size is not so large that the top bit is set. * The top bit of the block size member of the BlockLink_t structure is used * to determine who owns the block - the application or the kernel, so it * must be free. */ if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) { /* The wanted size is increased so it can contain a BlockLink_t * structure in addition to the requested amount of bytes. */ if( xWantedSize > 0 ) { xWantedSize += xHeapStructSize; /* Ensure that blocks are always aligned to the required number of * bytes. */ if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 ) { /* Byte alignment required. */ xWantedSize += ( secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) ); secureportASSERT( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) == 0 ); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) { /* Traverse the list from the start (lowest address) block until * one of adequate size is found. */ pxPreviousBlock = &xStart; pxBlock = xStart.pxNextFreeBlock; while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) { pxPreviousBlock = pxBlock; pxBlock = pxBlock->pxNextFreeBlock; } /* If the end marker was reached then a block of adequate size was * not found. */ if( pxBlock != pxEnd ) { /* Return the memory space pointed to - jumping over the * BlockLink_t structure at its start. */ pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); /* This block is being returned for use so must be taken out * of the list of free blocks. */ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; /* If the block is larger than required it can be split into * two. */ if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE ) { /* This block is to be split into two. Create a new * block following the number of bytes requested. The void * cast is used to prevent byte alignment warnings from the * compiler. */ pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 ); /* Calculate the sizes of two blocks split from the single * block. */ pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; pxBlock->xBlockSize = xWantedSize; /* Insert the new block into the list of free blocks. */ prvInsertBlockIntoFreeList( pxNewBlockLink ); } else { mtCOVERAGE_TEST_MARKER(); } xFreeBytesRemaining -= pxBlock->xBlockSize; if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) { xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; } else { mtCOVERAGE_TEST_MARKER(); } /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ pxBlock->xBlockSize |= xBlockAllocatedBit; pxBlock->pxNextFreeBlock = NULL; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } traceMALLOC( pvReturn, xWantedSize ); #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { extern void vApplicationMallocFailedHook( void ); vApplicationMallocFailedHook(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */ secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 ); return pvReturn; } /*-----------------------------------------------------------*/ void vPortFree( void * pv ) { uint8_t * puc = ( uint8_t * ) pv; BlockLink_t * pxLink; if( pv != NULL ) { /* The memory being freed will have an BlockLink_t structure immediately * before it. */ puc -= xHeapStructSize; /* This casting is to keep the compiler from issuing warnings. */ pxLink = ( void * ) puc; /* Check the block is actually allocated. */ secureportASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); secureportASSERT( pxLink->pxNextFreeBlock == NULL ); if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) { if( pxLink->pxNextFreeBlock == NULL ) { /* The block is being returned to the heap - it is no longer * allocated. */ pxLink->xBlockSize &= ~xBlockAllocatedBit; secureportDISABLE_NON_SECURE_INTERRUPTS(); { /* Add this block to the list of free blocks. */ xFreeBytesRemaining += pxLink->xBlockSize; traceFREE( pv, pxLink->xBlockSize ); prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); } secureportENABLE_NON_SECURE_INTERRUPTS(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } } /*-----------------------------------------------------------*/ size_t xPortGetFreeHeapSize( void ) { return xFreeBytesRemaining; } /*-----------------------------------------------------------*/ size_t xPortGetMinimumEverFreeHeapSize( void ) { return xMinimumEverFreeBytesRemaining; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/secure/heap/secure_heap.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_HEAP_H__ #define __SECURE_HEAP_H__ /* Standard includes. */ #include /** * @brief Allocates memory from heap. * * @param[in] xWantedSize The size of the memory to be allocated. * * @return Pointer to the memory region if the allocation is successful, NULL * otherwise. */ void * pvPortMalloc( size_t xWantedSize ); /** * @brief Frees the previously allocated memory. * * @param[in] pv Pointer to the memory to be freed. */ void vPortFree( void * pv ); /** * @brief Get the free heap size. * * @return Free heap size. */ size_t xPortGetFreeHeapSize( void ); /** * @brief Get the minimum ever free heap size. * * @return Minimum ever free heap size. */ size_t xPortGetMinimumEverFreeHeapSize( void ); #endif /* __SECURE_HEAP_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/secure/init/secure_init.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure init includes. */ #include "secure_init.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Constants required to manipulate the SCB. */ #define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */ #define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL ) #define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS ) #define secureinitSCB_AIRCR_PRIS_POS ( 14UL ) #define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS ) /** * @brief Constants required to manipulate the FPU. */ #define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define secureinitFPCCR_LSPENS_POS ( 29UL ) #define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS ) #define secureinitFPCCR_TS_POS ( 26UL ) #define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS ) #define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */ #define secureinitNSACR_CP10_POS ( 10UL ) #define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS ) #define secureinitNSACR_CP11_POS ( 11UL ) #define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS ) /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { *( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) | ( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) | ( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK ); } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* CP10 = 1 ==> Non-secure access to the Floating Point Unit is * permitted. CP11 should be programmed to the same value as CP10. */ *( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK ); /* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures * that we can enable/disable lazy stacking in port.c file. */ *( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK ); /* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP * registers (S16-S31) are also pushed to stack on exception entry and * restored on exception return. */ *( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK ); } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/secure/init/secure_init.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_INIT_H__ #define __SECURE_INIT_H__ /** * @brief De-prioritizes the non-secure exceptions. * * This is needed to ensure that the non-secure PendSV runs at the lowest * priority. Context switch is done in the non-secure PendSV handler. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_DePrioritizeNSExceptions( void ); /** * @brief Sets up the Floating Point Unit (FPU) for Non-Secure access. * * Also sets FPCCR.TS=1 to ensure that the content of the Floating Point * Registers are not leaked to the non-secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_EnableNSFPUAccess( void ); #endif /* __SECURE_INIT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/ARMv8M/secure/macros/secure_port_macros.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_PORT_MACROS_H__ #define __SECURE_PORT_MACROS_H__ /** * @brief Byte alignment requirements. */ #define secureportBYTE_ALIGNMENT 8 #define secureportBYTE_ALIGNMENT_MASK ( 0x0007 ) /** * @brief Macro to declare a function as non-secure callable. */ #if defined( __IAR_SYSTEMS_ICC__ ) #define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root #else #define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) ) #endif /** * @brief Set the secure PRIMASK value. */ #define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Set the non-secure PRIMASK value. */ #define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Read the PSP value in the given variable. */ #define secureportREAD_PSP( pucOutCurrentStackPointer ) \ __asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) ) /** * @brief Set the PSP to the given value. */ #define secureportSET_PSP( pucCurrentStackPointer ) \ __asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) ) /** * @brief Read the PSPLIM value in the given variable. */ #define secureportREAD_PSPLIM( pucOutStackLimit ) \ __asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) ) /** * @brief Set the PSPLIM to the given value. */ #define secureportSET_PSPLIM( pucStackLimit ) \ __asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) ) /** * @brief Set the NonSecure MSP to the given value. */ #define secureportSET_MSP_NS( pucMainStackPointer ) \ __asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) ) /** * @brief Set the CONTROL register to the given value. */ #define secureportSET_CONTROL( ulControl ) \ __asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" ) /** * @brief Read the Interrupt Program Status Register (IPSR) value in the given * variable. */ #define secureportREAD_IPSR( ulIPSR ) \ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) ) /** * @brief PRIMASK value to enable interrupts. */ #define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0 /** * @brief PRIMASK value to disable interrupts. */ #define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1 /** * @brief Disable secure interrupts. */ #define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Disable non-secure interrupts. * * This effectively disables context switches. */ #define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Enable non-secure interrupts. */ #define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL ) /** * @brief Assert definition. */ #define secureportASSERT( x ) \ if( ( x ) == 0 ) \ { \ secureportDISABLE_SECURE_INTERRUPTS(); \ secureportDISABLE_NON_SECURE_INTERRUPTS(); \ for( ; ; ) {; } \ } #endif /* __SECURE_PORT_MACROS_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/CCS/ARM_CM3/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM3 port. *----------------------------------------------------------*/ /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #if ( configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 ) #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ #endif /* Constants required to manipulate the core. Registers first... */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) /* ...then bits in the registers. */ #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) #define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) ) #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ #define portVECTACTIVE_MASK ( 0xFFUL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) /* The systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /* A fiddle factor to estimate the number of SysTick counts that would have * occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) /* Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ); /* * Exception handlers. */ void xPortSysTickHandler( void ); /* * Start first task is a separate function so it can be tested in isolation. */ extern void vPortStartFirstTask( void ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* Required to allow portasm.asm access the configMAX_SYSCALL_INTERRUPT_PRIORITY * setting. */ const uint32_t ulMaxSyscallInterruptPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY; /* Each task maintains its own interrupt status in the critical nesting * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* * The number of SysTick increments that make up one tick period. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulTimerCountsForOneTick = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * The maximum number of tick periods that can be suppressed is limited by the * 24 bit resolution of the SysTick timer. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t xMaximumPossibleSuppressedTicks = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Compensate for the CPU cycles that pass while the SysTick is stopped (low * power functionality only. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. */ #if ( configASSERT_DEFINED == 1 ) static uint8_t ucMaxSysCallPriority = 0; static uint32_t ulMaxPRIGROUPValue = 0; static const volatile uint8_t * const pcInterruptPriorityRegisters = ( uint8_t * ) portNVIC_IP_REGISTERS_OFFSET_16; #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ /* Offset added to account for the way the MCU uses the stack on entry/exit * of interrupts, and to ensure alignment. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */ /* Save code space by skipping register initialisation. */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). * * Artificially force an assert() to be triggered if configASSERT() is * defined, then stop here so application writers can catch the error. */ configASSERT( uxCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); for( ; ; ) { } } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API * functions can be called. ISR safe functions are those that end in * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { ulMaxPRIGROUPValue--; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); } #endif /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; /* Restore the clobbered interrupt priority register to its original * value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Start the first task. */ vPortStartFirstTask(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); uxCriticalNesting++; /* 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 * 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 * assert function also uses a critical section. */ if( uxCriticalNesting == 1 ) { configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { /* The SysTick runs at the lowest interrupt priority, so when this interrupt * executes all interrupts must be unmasked. There is therefore no need to * save and then restore the interrupt mask value as its value is already * known. */ ( void ) portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* A context switch is required. Context switching is performed in * the PendSV interrupt. Pend the PendSV interrupt. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 ); } /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) #pragma WEAK( vPortSuppressTicksAndSleep ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm( " cpsid i"); __asm( " dsb"); __asm( " isb"); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm( " cpsie i"); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm( " dsb"); __asm( " wfi"); __asm( " isb"); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm( " cpsie i"); __asm( " dsb"); __asm( " isb"); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm( " cpsid i"); __asm( " dsb"); __asm( " isb"); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm( " cpsie i"); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ /* * Setup the systick timer to generate the tick interrupts at the required * frequency. */ #pragma WEAK( vPortSetupTimerInterrupt ) void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and clear the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); } /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { extern uint32_t ulPortGetIPSR( void ); uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; ulCurrentInterrupt = ulPortGetIPSR(); /* Is the interrupt number a user defined interrupt? */ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /* Look up the interrupt's priority. */ ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Interrupts that use the FreeRTOS API must not be left at their * default priority of zero as that is the highest possible priority, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * and therefore also guaranteed to be invalid. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } /* Priority grouping: The interrupt controller (NVIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined * to be pre-emption priority bits. The following assertion will fail if * this is not the case (if some bits represent a sub-priority). * * If the application only uses CMSIS libraries for interrupt * configuration then the correct setting can be achieved on all Cortex-M * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * scheduler. Note however that some vendor specific peripheral libraries * assume a non-zero priority group setting, in which cases using a value * of zero will result in unpredictable behaviour. */ configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); } #endif /* configASSERT_DEFINED */ ================================================ FILE: FreeRTOS-comparison/portable/CCS/ARM_CM3/portasm.asm ================================================ ;/* ; * FreeRTOS Kernel V10.5.1 ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * this software and associated documentation files (the "Software"), to deal in ; * the Software without restriction, including without limitation the rights to ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * the Software, and to permit persons to whom the Software is furnished to do so, ; * subject to the following conditions: ; * ; * The above copyright notice and this permission notice shall be included in all ; * copies or substantial portions of the Software. ; * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * ; * https://www.FreeRTOS.org ; * https://github.com/FreeRTOS ; * ; */ .thumb .ref pxCurrentTCB .ref vTaskSwitchContext .ref ulMaxSyscallInterruptPriority .def xPortPendSVHandler .def ulPortGetIPSR .def vPortSVCHandler .def vPortStartFirstTask NVICOffsetConst: .word 0xE000ED08 CPACRConst: .word 0xE000ED88 pxCurrentTCBConst: .word pxCurrentTCB ulMaxSyscallInterruptPriorityConst: .word ulMaxSyscallInterruptPriority ; ----------------------------------------------------------- .align 4 ulPortGetIPSR: .asmfunc mrs r0, ipsr bx r14 .endasmfunc ; ----------------------------------------------------------- .align 4 vPortSetInterruptMask: .asmfunc push {r0} ldr r0, ulMaxSyscallInterruptPriorityConst msr basepri, r0 pop {r0} bx r14 .endasmfunc ; ----------------------------------------------------------- .align 4 xPortPendSVHandler: .asmfunc mrs r0, psp isb ;/* Get the location of the current TCB. */ ldr r3, pxCurrentTCBConst ldr r2, [r3] ;/* Save the core registers. */ stmdb r0!, {r4-r11} ;/* Save the new top of stack into the first member of the TCB. */ str r0, [r2] stmdb sp!, {r3, r14} ldr r0, ulMaxSyscallInterruptPriorityConst ldr r1, [r0] msr basepri, r1 dsb isb bl vTaskSwitchContext mov r0, #0 msr basepri, r0 ldmia sp!, {r3, r14} ;/* The first item in pxCurrentTCB is the task top of stack. */ ldr r1, [r3] ldr r0, [r1] ;/* Pop the core registers. */ ldmia r0!, {r4-r11} msr psp, r0 isb bx r14 .endasmfunc ; ----------------------------------------------------------- .align 4 vPortSVCHandler: .asmfunc ;/* Get the location of the current TCB. */ ldr r3, pxCurrentTCBConst ldr r1, [r3] ldr r0, [r1] ;/* Pop the core registers. */ ldmia r0!, {r4-r11} msr psp, r0 isb mov r0, #0 msr basepri, r0 orr r14, #0xd bx r14 .endasmfunc ; ----------------------------------------------------------- .align 4 vPortStartFirstTask: .asmfunc ;/* Use the NVIC offset register to locate the stack. */ ldr r0, NVICOffsetConst ldr r0, [r0] ldr r0, [r0] ;/* Set the msp back to the start of the stack. */ msr msp, r0 ;/* Clear the bit that indicates the FPU is in use in case the FPU was used ;before the scheduler was started - which would otherwise result in the ;unnecessary leaving of space in the SVC stack for lazy saving of FPU ;registers. */ mov r0, #0 msr control, r0 ;/* Call SVC to start the first task. */ cpsie i cpsie f dsb isb svc #0 .endasmfunc ; ----------------------------------------------------------- ================================================ FILE: FreeRTOS-comparison/portable/CCS/ARM_CM3/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Compiler directives. */ #define portWEAK_SYMBOL __attribute__( ( weak ) ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ #define portYIELD() \ { \ /* Set a PendSV to request a context switch. */ \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ __asm( " dsb"); \ __asm( " isb"); \ } #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #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. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); #define portDISABLE_INTERRUPTS() \ { \ _set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \ __asm( " dsb"); \ __asm( " isb"); \ } #define portENABLE_INTERRUPTS() _set_interrupt_priority( 0 ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() #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 ) /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /* 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 * (which build with all the ports) will build. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* portNOP() is not required by this port. */ #define portNOP() /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/CCS/ARM_CM4F/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM4F port. *----------------------------------------------------------*/ /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #ifndef __TI_VFP_SUPPORT__ #error This port can only be used when the project options are configured to enable hardware floating point support. #endif #if ( configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 ) #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ #endif /* Constants required to manipulate the core. Registers first... */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) /* ...then bits in the registers. */ #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) #define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) ) #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ #define portVECTACTIVE_MASK ( 0xFFUL ) /* Constants required to manipulate the VFP. */ #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_EXC_RETURN ( 0xfffffffd ) /* The systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /* A fiddle factor to estimate the number of SysTick counts that would have * occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) /* Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ); /* * Exception handlers. */ void xPortSysTickHandler( void ); /* * Start first task is a separate function so it can be tested in isolation. */ extern void vPortStartFirstTask( void ); /* * Turn the VFP on. */ extern void vPortEnableVFP( void ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* Required to allow portasm.asm access the configMAX_SYSCALL_INTERRUPT_PRIORITY * setting. */ const uint32_t ulMaxSyscallInterruptPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY; /* Each task maintains its own interrupt status in the critical nesting * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* * The number of SysTick increments that make up one tick period. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulTimerCountsForOneTick = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * The maximum number of tick periods that can be suppressed is limited by the * 24 bit resolution of the SysTick timer. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t xMaximumPossibleSuppressedTicks = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Compensate for the CPU cycles that pass while the SysTick is stopped (low * power functionality only. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. */ #if ( configASSERT_DEFINED == 1 ) static uint8_t ucMaxSysCallPriority = 0; static uint32_t ulMaxPRIGROUPValue = 0; static const volatile uint8_t * const pcInterruptPriorityRegisters = ( uint8_t * ) portNVIC_IP_REGISTERS_OFFSET_16; #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ /* Offset added to account for the way the MCU uses the stack on entry/exit * of interrupts, and to ensure alignment. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */ /* Save code space by skipping register initialisation. */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ /* A save method is being used that requires each task to maintain its * own exec return value. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). * * Artificially force an assert() to be triggered if configASSERT() is * defined, then stop here so application writers can catch the error. */ configASSERT( uxCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); for( ; ; ) { } } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API * functions can be called. ISR safe functions are those that end in * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { ulMaxPRIGROUPValue--; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); } #endif /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; /* Restore the clobbered interrupt priority register to its original * value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Ensure the VFP is enabled - it should be anyway. */ vPortEnableVFP(); /* Lazy save always. */ *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; /* Start the first task. */ vPortStartFirstTask(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); uxCriticalNesting++; /* 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 * 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 * assert function also uses a critical section. */ if( uxCriticalNesting == 1 ) { configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { /* The SysTick runs at the lowest interrupt priority, so when this interrupt * executes all interrupts must be unmasked. There is therefore no need to * save and then restore the interrupt mask value as its value is already * known. */ ( void ) portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* A context switch is required. Context switching is performed in * the PendSV interrupt. Pend the PendSV interrupt. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 ); } /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) #pragma WEAK( vPortSuppressTicksAndSleep ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm( " cpsid i"); __asm( " dsb"); __asm( " isb"); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm( " cpsie i"); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm( " dsb"); __asm( " wfi"); __asm( " isb"); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm( " cpsie i"); __asm( " dsb"); __asm( " isb"); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm( " cpsid i"); __asm( " dsb"); __asm( " isb"); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm( " cpsie i"); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ /* * Setup the systick timer to generate the tick interrupts at the required * frequency. */ #pragma WEAK( vPortSetupTimerInterrupt ) void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and clear the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); } /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { extern uint32_t ulPortGetIPSR( void ); uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; ulCurrentInterrupt = ulPortGetIPSR(); /* Is the interrupt number a user defined interrupt? */ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /* Look up the interrupt's priority. */ ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Interrupts that use the FreeRTOS API must not be left at their * default priority of zero as that is the highest possible priority, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * and therefore also guaranteed to be invalid. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } /* Priority grouping: The interrupt controller (NVIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined * to be pre-emption priority bits. The following assertion will fail if * this is not the case (if some bits represent a sub-priority). * * If the application only uses CMSIS libraries for interrupt * configuration then the correct setting can be achieved on all Cortex-M * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * scheduler. Note however that some vendor specific peripheral libraries * assume a non-zero priority group setting, in which cases using a value * of zero will result in unpredictable behaviour. */ configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); } #endif /* configASSERT_DEFINED */ ================================================ FILE: FreeRTOS-comparison/portable/CCS/ARM_CM4F/portasm.asm ================================================ ;/* ; * FreeRTOS Kernel V10.5.1 ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * this software and associated documentation files (the "Software"), to deal in ; * the Software without restriction, including without limitation the rights to ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * the Software, and to permit persons to whom the Software is furnished to do so, ; * subject to the following conditions: ; * ; * The above copyright notice and this permission notice shall be included in all ; * copies or substantial portions of the Software. ; * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * ; * https://www.FreeRTOS.org ; * https://github.com/FreeRTOS ; * ; */ .thumb .ref pxCurrentTCB .ref vTaskSwitchContext .ref ulMaxSyscallInterruptPriority .def xPortPendSVHandler .def ulPortGetIPSR .def vPortSVCHandler .def vPortStartFirstTask .def vPortEnableVFP NVICOffsetConst: .word 0xE000ED08 CPACRConst: .word 0xE000ED88 pxCurrentTCBConst: .word pxCurrentTCB ulMaxSyscallInterruptPriorityConst: .word ulMaxSyscallInterruptPriority ; ----------------------------------------------------------- .align 4 ulPortGetIPSR: .asmfunc mrs r0, ipsr bx r14 .endasmfunc ; ----------------------------------------------------------- .align 4 vPortSetInterruptMask: .asmfunc push {r0} ldr r0, ulMaxSyscallInterruptPriorityConst msr basepri, r0 pop {r0} bx r14 .endasmfunc ; ----------------------------------------------------------- .align 4 xPortPendSVHandler: .asmfunc mrs r0, psp isb ;/* Get the location of the current TCB. */ ldr r3, pxCurrentTCBConst ldr r2, [r3] ;/* Is the task using the FPU context? If so, push high vfp registers. */ tst r14, #0x10 it eq vstmdbeq r0!, {s16-s31} ;/* Save the core registers. */ stmdb r0!, {r4-r11, r14} ;/* Save the new top of stack into the first member of the TCB. */ str r0, [r2] stmdb sp!, {r0, r3} ldr r0, ulMaxSyscallInterruptPriorityConst ldr r1, [r0] msr basepri, r1 dsb isb bl vTaskSwitchContext mov r0, #0 msr basepri, r0 ldmia sp!, {r0, r3} ;/* The first item in pxCurrentTCB is the task top of stack. */ ldr r1, [r3] ldr r0, [r1] ;/* Pop the core registers. */ ldmia r0!, {r4-r11, r14} ;/* Is the task using the FPU context? If so, pop the high vfp registers ;too. */ tst r14, #0x10 it eq vldmiaeq r0!, {s16-s31} msr psp, r0 isb bx r14 .endasmfunc ; ----------------------------------------------------------- .align 4 vPortSVCHandler: .asmfunc ;/* Get the location of the current TCB. */ ldr r3, pxCurrentTCBConst ldr r1, [r3] ldr r0, [r1] ;/* Pop the core registers. */ ldmia r0!, {r4-r11, r14} msr psp, r0 isb mov r0, #0 msr basepri, r0 bx r14 .endasmfunc ; ----------------------------------------------------------- .align 4 vPortStartFirstTask: .asmfunc ;/* Use the NVIC offset register to locate the stack. */ ldr r0, NVICOffsetConst ldr r0, [r0] ldr r0, [r0] ;/* Set the msp back to the start of the stack. */ msr msp, r0 ;/* Clear the bit that indicates the FPU is in use in case the FPU was used ;before the scheduler was started - which would otherwise result in the ;unnecessary leaving of space in the SVC stack for lazy saving of FPU ;registers. */ mov r0, #0 msr control, r0 ;/* Call SVC to start the first task. */ cpsie i cpsie f dsb isb svc #0 .endasmfunc ; ----------------------------------------------------------- .align 4 vPortEnableVFP: .asmfunc ;/* The FPU enable bits are in the CPACR. */ ldr.w r0, CPACRConst ldr r1, [r0] ;/* Enable CP10 and CP11 coprocessors, then save back. */ orr r1, r1, #( 0xf << 20 ) str r1, [r0] bx r14 .endasmfunc .end ; ----------------------------------------------------------- ================================================ FILE: FreeRTOS-comparison/portable/CCS/ARM_CM4F/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Scheduler utilities. */ #define portYIELD() \ { \ /* Set a PendSV to request a context switch. */ \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ __asm( " dsb"); \ __asm( " isb"); \ } #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #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. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); #define portDISABLE_INTERRUPTS() \ { \ _set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \ __asm( " dsb"); \ __asm( " isb"); \ } #define portENABLE_INTERRUPTS() _set_interrupt_priority( 0 ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() #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 ) /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /* 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 * (which build with all the ports) will build. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* portNOP() is not required by this port. */ #define portNOP() /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/CCS/ARM_Cortex-R4/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* FreeRTOS includes. */ #include "FreeRTOS.h" #include "task.h" /*-----------------------------------------------------------*/ /* Count of the critical section nesting depth. */ uint32_t ulCriticalNesting = 9999; /*-----------------------------------------------------------*/ /* Registers required to configure the RTI. */ #define portRTI_GCTRL_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC00 ) ) #define portRTI_TBCTRL_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC04 ) ) #define portRTI_COMPCTRL_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC0C ) ) #define portRTI_CNT0_FRC0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC10 ) ) #define portRTI_CNT0_UC0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC14 ) ) #define portRTI_CNT0_CPUC0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC18 ) ) #define portRTI_CNT0_COMP0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC50 ) ) #define portRTI_CNT0_UDCP0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC54 ) ) #define portRTI_SETINTENA_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC80 ) ) #define portRTI_CLEARINTENA_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC84 ) ) #define portRTI_INTFLAG_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC88 ) ) /* Constants required to set up the initial stack of each task. */ #define portINITIAL_SPSR ( ( StackType_t ) 0x1F ) #define portINITIAL_FPSCR ( ( StackType_t ) 0x00 ) #define portINSTRUCTION_SIZE ( ( StackType_t ) 0x04 ) #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) /* The number of words on the stack frame between the saved Top Of Stack and R0 (in which the parameters are passed. */ #define portSPACE_BETWEEN_TOS_AND_PARAMETERS ( 12 ) /*-----------------------------------------------------------*/ /* vPortStartFirstSTask() is defined in portASM.asm */ extern void vPortStartFirstTask( void ); /*-----------------------------------------------------------*/ /* Saved as part of the task context. Set to pdFALSE if the task does not require an FPU context. */ uint32_t ulTaskHasFPUContext = 0; /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { StackType_t *pxOriginalTOS; pxOriginalTOS = pxTopOfStack; #if __TI_VFP_SUPPORT__ { /* Ensure the stack is correctly aligned on exit. */ pxTopOfStack--; } #endif /* Setup the initial stack of the task. The stack is set exactly as expected by the portRESTORE_CONTEXT() macro. */ /* 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 address appear as it would within an IRQ ISR. */ *pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */ pxTopOfStack--; #ifdef portPRELOAD_TASK_REGISTERS { *pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */ pxTopOfStack--; } #else { pxTopOfStack -= portSPACE_BETWEEN_TOS_AND_PARAMETERS; } #endif /* Function parameters are passed in R0. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; /* Set the status register for system mode, with interrupts enabled. */ *pxTopOfStack = ( StackType_t ) ( ( _get_CPSR() & ~0xFF ) | portINITIAL_SPSR ); if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 ) { /* The task will start in thumb mode. */ *pxTopOfStack |= portTHUMB_MODE_BIT; } #ifdef __TI_VFP_SUPPORT__ { pxTopOfStack--; /* 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 registers. */ *pxTopOfStack = pdFALSE; } #endif return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvSetupTimerInterrupt(void) { /* Disable timer 0. */ portRTI_GCTRL_REG &= 0xFFFFFFFEUL; /* Use the internal counter. */ portRTI_TBCTRL_REG = 0x00000000U; /* COMPSEL0 will use the RTIFRC0 counter. */ portRTI_COMPCTRL_REG = 0x00000000U; /* Initialise the counter and the prescale counter registers. */ portRTI_CNT0_UC0_REG = 0x00000000U; portRTI_CNT0_FRC0_REG = 0x00000000U; /* Set Prescalar for RTI clock. */ portRTI_CNT0_CPUC0_REG = 0x00000001U; portRTI_CNT0_COMP0_REG = ( configCPU_CLOCK_HZ / 2 ) / configTICK_RATE_HZ; portRTI_CNT0_UDCP0_REG = ( configCPU_CLOCK_HZ / 2 ) / configTICK_RATE_HZ; /* Clear interrupts. */ portRTI_INTFLAG_REG = 0x0007000FU; portRTI_CLEARINTENA_REG = 0x00070F0FU; /* Enable the compare 0 interrupt. */ portRTI_SETINTENA_REG = 0x00000001U; portRTI_GCTRL_REG |= 0x00000001U; } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler(void) { /* Start the timer that generates the tick ISR. */ prvSetupTimerInterrupt(); /* Reset the critical section nesting count read to execute the first task. */ ulCriticalNesting = 0; /* Start the first task. This is done from portASM.asm as ARM mode must be used. */ vPortStartFirstTask(); /* Should not get here! */ return pdFAIL; } /*-----------------------------------------------------------*/ /* * See header file for description. */ void vPortEndScheduler(void) { /* Not implemented in ports where there is nothing to return to. Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if configUSE_PREEMPTION == 0 /* The cooperative scheduler requires a normal IRQ service routine to * simply increment the system tick. */ __interrupt void vPortNonPreemptiveTick( void ) { /* clear clock interrupt flag */ portRTI_INTFLAG_REG = 0x00000001; /* Increment the tick count - this may make a delaying task ready to run - but a context switch is not performed. */ xTaskIncrementTick(); } #else /* ************************************************************************** * 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 * is set to 1 in portmacro.h ************************************************************************** */ void vPortPreemptiveTick( void ); #endif /*-----------------------------------------------------------*/ /* * Disable interrupts, and keep a count of the nesting depth. */ void vPortEnterCritical( void ) { /* Disable interrupts as per portDISABLE_INTERRUPTS(); */ portDISABLE_INTERRUPTS(); /* Now interrupts are disabled ulCriticalNesting can be accessed directly. Increment ulCriticalNesting to keep a count of how many times portENTER_CRITICAL() has been called. */ ulCriticalNesting++; } /*-----------------------------------------------------------*/ /* * Decrement the critical nesting count, and if it has reached zero, re-enable * interrupts. */ void vPortExitCritical( void ) { if( ulCriticalNesting > 0 ) { /* Decrement the nesting count as we are leaving a critical section. */ ulCriticalNesting--; /* If the nesting level has reached zero then interrupts should be re-enabled. */ if( ulCriticalNesting == 0 ) { /* Enable interrupts as per portENABLE_INTERRUPTS(). */ portENABLE_INTERRUPTS(); } } } /*-----------------------------------------------------------*/ #if __TI_VFP_SUPPORT__ void vPortTaskUsesFPU( void ) { extern void vPortInitialiseFPSCR( void ); /* A task is registering the fact that it needs an FPU context. Set the FPU flag (saved as part of the task context. */ ulTaskHasFPUContext = pdTRUE; /* Initialise the floating point status register. */ vPortInitialiseFPSCR(); } #endif /* __TI_VFP_SUPPORT__ */ /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/CCS/ARM_Cortex-R4/portASM.asm ================================================ ;/* ; * FreeRTOS Kernel V10.5.1 ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * this software and associated documentation files (the "Software"), to deal in ; * the Software without restriction, including without limitation the rights to ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * the Software, and to permit persons to whom the Software is furnished to do so, ; * subject to the following conditions: ; * ; * The above copyright notice and this permission notice shall be included in all ; * copies or substantial portions of the Software. ; * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * ; * https://www.FreeRTOS.org ; * https://github.com/FreeRTOS ; * ; */ .text .arm .ref vTaskSwitchContext .ref xTaskIncrementTick .ref ulTaskHasFPUContext .ref pxCurrentTCB ;/*-----------------------------------------------------------*/ ; ; Save Task Context ; portSAVE_CONTEXT .macro DSB ; Push R0 as we are going to use it STMDB SP!, {R0} ; Set R0 to point to the task stack pointer. STMDB SP,{SP}^ SUB SP, SP, #4 LDMIA SP!,{R0} ; Push the return address onto the stack. STMDB R0!, {LR} ; Now LR has been saved, it can be used instead of R0. MOV LR, R0 ; Pop R0 so it can be saved onto the task stack. LDMIA SP!, {R0} ; Push all the system mode registers onto the task stack. STMDB LR,{R0-LR}^ SUB LR, LR, #60 ; Push the SPSR onto the task stack. MRS R0, SPSR STMDB LR!, {R0} .if (__TI_VFP_SUPPORT__) ;Determine if the task maintains an FPU context. LDR R0, ulFPUContextConst LDR R0, [R0] ; Test the flag CMP R0, #0 ; If the task is not using a floating point context then skip the ; saving of the FPU registers. BEQ $+16 FSTMDBD LR!, {D0-D15} FMRX R1, FPSCR STMFD LR!, {R1} ; Save the flag STMDB LR!, {R0} .endif ; Store the new top of stack for the task. LDR R0, pxCurrentTCBConst LDR R0, [R0] STR LR, [R0] .endm ;/*-----------------------------------------------------------*/ ; ; Restore Task Context ; portRESTORE_CONTEXT .macro LDR R0, pxCurrentTCBConst LDR R0, [R0] LDR LR, [R0] .if (__TI_VFP_SUPPORT__) ; The floating point context flag is the first thing on the stack. LDR R0, ulFPUContextConst LDMFD LR!, {R1} STR R1, [R0] ; Test the flag CMP R1, #0 ; If the task is not using a floating point context then skip the ; VFP register loads. BEQ $+16 ; Restore the floating point context. LDMFD LR!, {R0} FLDMIAD LR!, {D0-D15} FMXR FPSCR, R0 .endif ; Get the SPSR from the stack. LDMFD LR!, {R0} MSR SPSR_CSXF, R0 ; Restore all system mode registers for the task. LDMFD LR, {R0-R14}^ ; Restore the return address. LDR LR, [LR, #+60] ; And return - correcting the offset in the LR to obtain the ; correct address. SUBS PC, LR, #4 .endm ;/*-----------------------------------------------------------*/ ; Start the first task by restoring its context. .def vPortStartFirstTask vPortStartFirstTask: portRESTORE_CONTEXT ;/*-----------------------------------------------------------*/ ; Yield to another task. .def vPortYieldProcessor vPortYieldProcessor: ; Within an IRQ ISR the link register has an offset from the true return ; address. SWI doesn't do this. Add the offset manually so the ISR ; return code can be used. ADD LR, LR, #4 ; First save the context of the current task. portSAVE_CONTEXT ; Select the next task to execute. */ BL vTaskSwitchContext ; Restore the context of the task selected to execute. portRESTORE_CONTEXT ;/*-----------------------------------------------------------*/ ; Yield to another task from within the FreeRTOS API .def vPortYeildWithinAPI vPortYeildWithinAPI: ; Save the context of the current task. portSAVE_CONTEXT ; Clear SSI flag. MOVW R0, #0xFFF4 MOVT R0, #0xFFFF LDR R0, [R0] ; Select the next task to execute. */ BL vTaskSwitchContext ; Restore the context of the task selected to execute. portRESTORE_CONTEXT ;/*-----------------------------------------------------------*/ ; Preemptive Tick .def vPortPreemptiveTick vPortPreemptiveTick: ; Save the context of the current task. portSAVE_CONTEXT ; Clear interrupt flag MOVW R0, #0xFC88 MOVT R0, #0xFFFF MOV R1, #1 STR R1, [R0] ; Increment the tick count, making any adjustments to the blocked lists ; that may be necessary. BL xTaskIncrementTick ; Select the next task to execute. CMP R0, #0 BLNE vTaskSwitchContext ; Restore the context of the task selected to execute. portRESTORE_CONTEXT ;------------------------------------------------------------------------------- .if (__TI_VFP_SUPPORT__) .def vPortInitialiseFPSCR vPortInitialiseFPSCR: MOV R0, #0 FMXR FPSCR, R0 BX LR .endif ;__TI_VFP_SUPPORT__ pxCurrentTCBConst .word pxCurrentTCB ulFPUContextConst .word ulTaskHasFPUContext ;------------------------------------------------------------------------------- ================================================ FILE: FreeRTOS-comparison/portable/CCS/ARM_Cortex-R4/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORTMACRO_H__ #define __PORTMACRO_H__ /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if (configUSE_16_BIT_TICKS == 1) typedef uint16_t TickType_t; #define portMAX_DELAY (TickType_t) 0xFFFF #else typedef uint32_t TickType_t; #define portMAX_DELAY (TickType_t) 0xFFFFFFFFF /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /* Architecture specifics. */ #define portSTACK_GROWTH (-1) #define portTICK_PERIOD_MS ((TickType_t) 1000 / configTICK_RATE_HZ) #define portBYTE_ALIGNMENT 8 /* Critical section handling. */ extern void vPortEnterCritical(void); extern void vPortExitCritical(void); #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() #define portDISABLE_INTERRUPTS() asm( " CPSID I" ) #define portENABLE_INTERRUPTS() asm( " CPSIE I" ) /* Scheduler utilities. */ #pragma SWI_ALIAS( vPortYield, 0 ) extern void vPortYield( void ); #define portYIELD() vPortYield() #define portSYS_SSIR1_REG ( * ( ( volatile uint32_t * ) 0xFFFFFFB0 ) ) #define portSYS_SSIR1_SSKEY ( 0x7500UL ) #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 ) #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif /* Architecture specific optimisations. */ #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #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. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /* Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION(vFunction, pvParameters) void vFunction(void *pvParameters) #define portTASK_FUNCTION_PROTO(vFunction, pvParameters) void vFunction(void *pvParameters) #endif /* __PORTMACRO_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/CCS/MSP430X/data_model.h ================================================ ;/* ; * FreeRTOS Kernel V10.5.1 ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * this software and associated documentation files (the "Software"), to deal in ; * the Software without restriction, including without limitation the rights to ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * the Software, and to permit persons to whom the Software is furnished to do so, ; * subject to the following conditions: ; * ; * The above copyright notice and this permission notice shall be included in all ; * copies or substantial portions of the Software. ; * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * ; * https://www.FreeRTOS.org ; * https://github.com/FreeRTOS ; * ; */ .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__ ) .define "calla", call_x .define "reta", ret_x .else .define "call", call_x .define "ret", ret_x .endif ================================================ FILE: FreeRTOS-comparison/portable/CCS/MSP430X/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the MSP430X port. *----------------------------------------------------------*/ /* Constants required for hardware setup. The tick ISR runs off the ACLK, not the MCLK. */ #define portACLK_FREQUENCY_HZ ( ( TickType_t ) 32768 ) #define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 ) #define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x08 ) /* We require the address of the pxCurrentTCB variable, but don't want to know any details of its type. */ typedef void TCB_t; extern volatile TCB_t * volatile pxCurrentTCB; /* 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 critical section is exited the count is decremented - with interrupts only being re-enabled if the count is zero. 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 sequence. */ volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING; /*-----------------------------------------------------------*/ /* * Sets up the periodic ISR used for the RTOS tick. This uses timer 0, but * could have alternatively used the watchdog timer or timer 1. */ void vPortSetupTimerInterrupt( void ); /*-----------------------------------------------------------*/ /* * Initialise the stack of a task to look exactly as if a call to * portSAVE_CONTEXT had been called. * * See the header file portable.h. */ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { uint16_t *pusTopOfStack; uint32_t *pulTopOfStack, ulTemp; /* 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. *pxTopOfStack = ( StackType_t ) 0x1111; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x2222; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x3333; pxTopOfStack--; */ /* Data types are need either 16 bits or 32 bits depending on the data and code model used. */ if( sizeof( pxCode ) == sizeof( uint16_t ) ) { pusTopOfStack = ( uint16_t * ) pxTopOfStack; ulTemp = ( uint32_t ) pxCode; *pusTopOfStack = ( uint16_t ) ulTemp; } else { /* Make room for a 20 bit value stored as a 32 bit value. */ pusTopOfStack = ( uint16_t * ) pxTopOfStack; pusTopOfStack--; pulTopOfStack = ( uint32_t * ) pusTopOfStack; *pulTopOfStack = ( uint32_t ) pxCode; } pusTopOfStack--; *pusTopOfStack = portFLAGS_INT_ENABLED; pusTopOfStack -= ( sizeof( StackType_t ) / 2 ); /* From here on the size of stacked items depends on the memory model. */ pxTopOfStack = ( StackType_t * ) pusTopOfStack; /* Next the general purpose registers. */ #ifdef PRELOAD_REGISTER_VALUES *pxTopOfStack = ( StackType_t ) 0xffff; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xeeee; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xdddd; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xbbbb; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xaaaa; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x9999; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x8888; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x5555; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x6666; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x5555; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x4444; pxTopOfStack--; #else pxTopOfStack -= 3; *pxTopOfStack = ( StackType_t ) pvParameters; pxTopOfStack -= 9; #endif /* 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 initially set to zero. */ *pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING; /* 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. */ return pxTopOfStack; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* It is unlikely that the MSP430 port will get stopped. If required simply disable the tick interrupt here. */ } /*-----------------------------------------------------------*/ /* * Hardware initialisation to generate the RTOS tick. */ void vPortSetupTimerInterrupt( void ) { vApplicationSetupTimerInterrupt(); } /*-----------------------------------------------------------*/ #pragma vector=configTICK_VECTOR interrupt void vTickISREntry( void ) { extern void vPortTickISR( void ); __bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF ); #if configUSE_PREEMPTION == 1 extern void vPortPreemptiveTickISR( void ); vPortPreemptiveTickISR(); #else extern void vPortCooperativeTickISR( void ); vPortCooperativeTickISR(); #endif } ================================================ FILE: FreeRTOS-comparison/portable/CCS/MSP430X/portext.asm ================================================ ;/* ; * FreeRTOS Kernel V10.5.1 ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * this software and associated documentation files (the "Software"), to deal in ; * the Software without restriction, including without limitation the rights to ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * the Software, and to permit persons to whom the Software is furnished to do so, ; * subject to the following conditions: ; * ; * The above copyright notice and this permission notice shall be included in all ; * copies or substantial portions of the Software. ; * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * ; * https://www.FreeRTOS.org ; * https://github.com/FreeRTOS ; * ; */ ; * The definition of the "register test" tasks, as described at the top of ; * main.c .include data_model.h .global xTaskIncrementTick .global vTaskSwitchContext .global vPortSetupTimerInterrupt .global pxCurrentTCB .global usCriticalNesting .def vPortPreemptiveTickISR .def vPortCooperativeTickISR .def vPortYield .def xPortStartScheduler ;----------------------------------------------------------- portSAVE_CONTEXT .macro ;Save the remaining registers. pushm_x #12, r15 mov.w &usCriticalNesting, r14 push_x r14 mov_x &pxCurrentTCB, r12 mov_x sp, 0( r12 ) .endm ;----------------------------------------------------------- portRESTORE_CONTEXT .macro mov_x &pxCurrentTCB, r12 mov_x @r12, sp pop_x r15 mov.w r15, &usCriticalNesting popm_x #12, r15 nop pop.w sr nop ret_x .endm ;----------------------------------------------------------- ;* ;* The RTOS tick ISR. ;* ;* If the cooperative scheduler is in use this simply increments the tick ;* count. ;* ;* If the preemptive scheduler is in use a context switch can also occur. ;*/ .text .align 2 vPortPreemptiveTickISR: .asmfunc ; The sr is not saved in portSAVE_CONTEXT() because vPortYield() needs ;to save it manually before it gets modified (interrupts get disabled). push.w sr portSAVE_CONTEXT call_x #xTaskIncrementTick call_x #vTaskSwitchContext portRESTORE_CONTEXT .endasmfunc ;----------------------------------------------------------- .align 2 vPortCooperativeTickISR: .asmfunc ; The sr is not saved in portSAVE_CONTEXT() because vPortYield() needs ;to save it manually before it gets modified (interrupts get disabled). push.w sr portSAVE_CONTEXT call_x #xTaskIncrementTick portRESTORE_CONTEXT .endasmfunc ;----------------------------------------------------------- ; ; Manual context switch called by the portYIELD() macro. ; .align 2 vPortYield: .asmfunc ; The sr needs saving before it is modified. push.w sr ; Now the SR is stacked we can disable interrupts. dint nop ; Save the context of the current task. portSAVE_CONTEXT ; Select the next task to run. call_x #vTaskSwitchContext ; Restore the context of the new task. portRESTORE_CONTEXT .endasmfunc ;----------------------------------------------------------- ; ; Start off the scheduler by initialising the RTOS tick timer, then restoring ; the context of the first task. ; .align 2 xPortStartScheduler: .asmfunc ; Setup the hardware to generate the tick. Interrupts are disabled ; when this function is called. call_x #vPortSetupTimerInterrupt ; Restore the context of the first task that is going to run. portRESTORE_CONTEXT .endasmfunc ;----------------------------------------------------------- .end ================================================ FILE: FreeRTOS-comparison/portable/CCS/MSP430X/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Hardware includes. */ #include "msp430.h" /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT int #define portBASE_TYPE portSHORT /* The stack type changes depending on the data model. */ #ifdef __LARGE_DATA_MODEL__ #define portSTACK_TYPE uint32_t #else #define portSTACK_TYPE uint16_t #define portPOINTER_SIZE_TYPE uint16_t #endif typedef portSTACK_TYPE StackType_t; typedef short BaseType_t; typedef unsigned short UBaseType_t; #if( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #endif /*-----------------------------------------------------------*/ /* Interrupt control macros. */ #define portDISABLE_INTERRUPTS() _disable_interrupt(); _nop() #define portENABLE_INTERRUPTS() _enable_interrupt(); _nop() /*-----------------------------------------------------------*/ /* Critical section control macros. */ #define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 ) #define portENTER_CRITICAL() \ { \ extern volatile uint16_t usCriticalNesting; \ \ portDISABLE_INTERRUPTS(); \ \ /* Now interrupts are disabled usCriticalNesting can be accessed */ \ /* directly. Increment ulCriticalNesting to keep a count of how many */ \ /* times portENTER_CRITICAL() has been called. */ \ usCriticalNesting++; \ } #define portEXIT_CRITICAL() \ { \ extern volatile uint16_t usCriticalNesting; \ \ if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \ { \ /* Decrement the nesting count as we are leaving a critical section. */ \ usCriticalNesting--; \ \ /* If the nesting level has reached zero then interrupts should be */ \ /* re-enabled. */ \ if( usCriticalNesting == portNO_CRITICAL_SECTION_NESTING ) \ { \ portENABLE_INTERRUPTS(); \ } \ } \ } /*-----------------------------------------------------------*/ /* Task utilities. */ /* * Manual context switch called by portYIELD or taskYIELD. */ extern void vPortYield( void ); #define portYIELD() vPortYield() /*-----------------------------------------------------------*/ /* Hardware specifics. */ #define portBYTE_ALIGNMENT 2 #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portNOP() __no_operation() /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) extern void vTaskSwitchContext( void ); #define portYIELD_FROM_ISR( x ) do { if( x ) vPortYield(); } while( 0 ) void vApplicationSetupTimerInterrupt( void ); /* sizeof( int ) != sizeof( long ) so a full printf() library is required if run time stats information is to be displayed. */ #define portLU_PRINTF_SPECIFIER_REQUIRED #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/CMakeLists.txt ================================================ # FreeRTOS internal cmake file. Do not use it in user top-level project add_library(freertos_kernel_port STATIC # 16-Bit DOS ports for BCC $<$: BCC/16BitDOS/common/portcomn.c BCC/16BitDOS/Flsh186/port.c> $<$: BCC/16BitDOS/common/portcomn.c BCC/16BitDOS/PC/port.c> # ARMv7-M port for Texas Instruments Code Composer Studio $<$: CCS/ARM_CM3/port.c CCS/ARM_CM3/portasm.asm> # ARMv7E-M port for Texas Instruments Code Composer Studio $<$: CCS/ARM_CM4F/port.c CCS/ARM_CM4F/portasm.asm> # ARMv7-R port for Texas Instruments Code Composer Studio $<$: CCS/ARM_Cortex-R4/port.c CCS/ARM_Cortex-R4/portASM.asm> # Texas Instruments MSP430 port for Texas Instruments Code Composer Studio $<$: CCS/MSP430X/port.c CCS/MSP430X/portext.asm> # NXP (formerly Motorola, Freescale) Cold Fire and 68HCS12 ports for Code Warrior $<$: CodeWarrior/ColdFire_V1/port.c CodeWarrior/ColdFire_V1/portasm.S> $<$: CodeWarrior/ColdFire_V2/port.c CodeWarrior/ColdFire_V2/portasm.S> $<$: CodeWarrior/HCS12/port.c> # ARMv7-A port for GCC $<$: GCC/ARM_CA9/port.c GCC/ARM_CA9/portASM.S> # ARMv8-A ports for GCC $<$: GCC/ARM_CA53_64_BIT/port.c GCC/ARM_CA53_64_BIT/portASM.S> $<$: GCC/ARM_CA53_64_BIT_SRE/port.c GCC/ARM_CA53_64_BIT_SRE/portASM.S> # ARMv6-M port for GCC $<$: GCC/ARM_CM0/port.c> # ARMv6-M / Cortex-M0 Raspberry PI RP2040 port for GCC $<$: ThirdParty/GCC/RP2040/idle_task_static_memory.c ThirdParty/GCC/RP2040/port.c> # ARMv7-M ports for GCC $<$: GCC/ARM_CM3/port.c> $<$: GCC/ARM_CM3_MPU/port.c> # ARMv7E-M ports for GCC $<$: GCC/ARM_CM4_MPU/port.c> $<$: GCC/ARM_CM4F/port.c> $<$: GCC/ARM_CM7/r0p1/port.c> # ARMv8-M ports for GCC $<$: GCC/ARM_CM23/non_secure/port.c GCC/ARM_CM23/non_secure/portasm.c> $<$: GCC/ARM_CM23/secure/secure_context_port.c GCC/ARM_CM23/secure/secure_context.c GCC/ARM_CM23/secure/secure_heap.c GCC/ARM_CM23/secure/secure_init.c> $<$: GCC/ARM_CM23_NTZ/non_secure/port.c GCC/ARM_CM23_NTZ/non_secure/portasm.c> $<$: GCC/ARM_CM33/non_secure/port.c GCC/ARM_CM33/non_secure/portasm.c> $<$: GCC/ARM_CM33/secure/secure_context_port.c GCC/ARM_CM33/secure/secure_context.c GCC/ARM_CM33/secure/secure_heap.c GCC/ARM_CM33/secure/secure_init.c> $<$: GCC/ARM_CM33_NTZ/non_secure/port.c GCC/ARM_CM33_NTZ/non_secure/portasm.c> $<$: GCC/ARM_CM33_NTZ/non_secure/port.c GCC/ARM_CM33_NTZ/non_secure/portasm.c ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c> # ARMv8.1-M ports for GCC $<$: GCC/ARM_CM55/non_secure/port.c GCC/ARM_CM55/non_secure/portasm.c> $<$: GCC/ARM_CM55/secure/secure_context_port.c GCC/ARM_CM55/secure/secure_context.c GCC/ARM_CM55/secure/secure_heap.c GCC/ARM_CM55/secure/secure_init.c> $<$: GCC/ARM_CM55_NTZ/non_secure/port.c GCC/ARM_CM55_NTZ/non_secure/portasm.c> $<$: GCC/ARM_CM55_NTZ/non_secure/port.c GCC/ARM_CM55_NTZ/non_secure/portasm.c ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c> $<$: GCC/ARM_CM85/non_secure/port.c GCC/ARM_CM85/non_secure/portasm.c> $<$: GCC/ARM_CM85/secure/secure_context_port.c GCC/ARM_CM85/secure/secure_context.c GCC/ARM_CM85/secure/secure_heap.c GCC/ARM_CM85/secure/secure_init.c> $<$: GCC/ARM_CM85_NTZ/non_secure/port.c GCC/ARM_CM85_NTZ/non_secure/portasm.c> $<$: GCC/ARM_CM85_NTZ/non_secure/port.c GCC/ARM_CM85_NTZ/non_secure/portasm.c ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c> # ARMv7-R ports for GCC $<$: GCC/ARM_CR5/port.c GCC/ARM_CR5/portASM.S> $<$: GCC/ARM_CRx_No_GIC/port.c GCC/ARM_CRx_No_GIC/portASM.S> # ARMv4T ARM7TDMI ports for GCC $<$: GCC/ARM7_AT91FR40008/port.c GCC/ARM7_AT91FR40008/portISR.c> $<$: GCC/ARM7_AT91SAM7S/lib_AT91SAM7X256.c GCC/ARM7_AT91SAM7S/port.c GCC/ARM7_AT91SAM7S/portISR.c> $<$: GCC/ARM7_LPC2000/port.c GCC/ARM7_LPC2000/portISR.c> $<$: GCC/ARM7_LPC23xx/port.c GCC/ARM7_LPC23xx/portISR.c> $<$: GCC/STR75x/port.c GCC/STR75x/portISR.c> # Microchip (formerly Ateml) AVR8 ports for GCC $<$: GCC/ATMega323/port.c> $<$: ThirdParty/GCC/ATmega/port.c> $<$: ThirdParty/Partner-Supported-Ports/GCC/AVR_AVRDx/port.c> $<$: ThirdParty/Partner-Supported-Ports/GCC/AVR_Mega0/port.c> # Microchip (formerly Ateml) AVR32 port for GCC $<$: GCC/AVR32_UC3/exception.S GCC/AVR32_UC3/port.c> # NXP (formerly Motorola, Freescale) Cold Fire and 68HCS12 ports for GCC $<$: GCC/ColdFire_V2/port.c GCC/ColdFire_V2/portasm.S> $<$: GCC/HCS12/port.c> # Cortus APS3 soft core port for GCC $<$: GCC/CORTUS_APS3/port.c> # Renesas (formerly Hitach) H8S port for GCC $<$: GCC/H8S2329/port.c> # x86 / IA32 flat memory model port for GCC $<$: GCC/IA32_flat/port.c GCC/IA32_flat/portASM.S> # Xilinx MicroBlaze soft core ports for GCC $<$: GCC/MicroBlaze/port.c GCC/MicroBlaze/portasm.s> $<$: GCC/MicroBlazeV8/port.c GCC/MicroBlazeV8/port_exceptions.c GCC/MicroBlazeV8/portasm.S> $<$: GCC/MicroBlazeV9/port.c GCC/MicroBlazeV9/port_exceptions.c GCC/MicroBlazeV9/portasm.S> # Xilinx PCC4XX soft core ports for GCC $<$: GCC/PPC405_Xilinx/port.c GCC/PPC405_Xilinx/portasm.S> $<$: GCC/PPC440_Xilinx/port.c GCC/PPC440_Xilinx/portasm.S> # Texas Instruments MSP430 port for GCC $<$: GCC/MSP430F449/port.c> # Intel (formerly Altera) NIOS II soft core port for GCC $<$: GCC/NiosII/port.c GCC/NiosII/port_asm.S> # RISC-V architecture ports for GCC $<$: GCC/RISC-V/port.c GCC/RISC-V/portASM.S> $<$: GCC/RISC-V/port.c GCC/RISC-V/portASM.S> # Renesas RL78 port for GCC $<$: GCC/RL78/port.c GCC/RL78/portasm.S> # Renesas RX architecture ports for GCC $<$: GCC/RX100/port.c> $<$: GCC/RX200/port.c> $<$: GCC/RX600/port.c> $<$: GCC/RX600v2/port.c> $<$: GCC/RX700v3_DPFPU/port.c> # Infineon TriCore 1782 port for GCC $<$: GCC/TriCore_1782/port.c GCC/TriCore_1782/porttrap.c> # Synopsys ARC architecture ports for GCC $<$: ThirdParty/GCC/ARC_EM_HS/arc_freertos_exceptions.c ThirdParty/GCC/ARC_EM_HS/arc_support.s ThirdParty/GCC/ARC_EM_HS/freertos_tls.c ThirdParty/GCC/ARC_EM_HS/port.c> $<$: ThirdParty/GCC/ARC_v1/arc_freertos_exceptions.c ThirdParty/GCC/ARC_v1/arc_support.s ThirdParty/GCC/ARC_v1/port.c> # Posix Simulator port for GCC $<$: ThirdParty/GCC/Posix/port.c ThirdParty/GCC/Posix/utils/wait_for_event.c> # Xtensa LX / Espressif ESP32 port for GCC $<$: ThirdParty/GCC/Xtensa_ESP32/FreeRTOS-openocd.c ThirdParty/GCC/Xtensa_ESP32/port.c ThirdParty/GCC/Xtensa_ESP32/portasm.S ThirdParty/GCC/Xtensa_ESP32/xtensa_context.S ThirdParty/GCC/Xtensa_ESP32/xtensa_init.c ThirdParty/GCC/Xtensa_ESP32/xtensa_intr_asm.S ThirdParty/GCC/Xtensa_ESP32/xtensa_intr.c ThirdParty/GCC/Xtensa_ESP32/xtensa_loadstore_handler.S ThirdParty/GCC/Xtensa_ESP32/xtensa_overlay_os_hook.c ThirdParty/GCC/Xtensa_ESP32/xtensa_vector_defaults.S ThirdParty/GCC/Xtensa_ESP32/xtensa_vectors.S> # Renesas (formerly NEC) 78K port for IAR EW78K $<$: IAR/78K0R/port.c IAR/78K0R/portasm.s26> # ARMv7-A ports for IAR EWARM $<$: IAR/ARM_CA5_No_GIC/port.c IAR/ARM_CA5_No_GIC/portASM.s> $<$: IAR/ARM_CA9/port.c IAR/ARM_CA9/portASM.s> # ARMv6-M port for IAR EWARM $<$: IAR/ARM_CM0/port.c IAR/ARM_CM0/portasm.s> # ARMv7-M port for IAR EWARM $<$: IAR/ARM_CM3/port.c IAR/ARM_CM3/portasm.s> # ARMv7E-M ports for IAR EWARM $<$: IAR/ARM_CM4F/port.c IAR/ARM_CM4F/portasm.s> $<$: IAR/ARM_CM4F_MPU/port.c IAR/ARM_CM4F_MPU/portasm.s> $<$: IAR/ARM_CM7/r0p1/port.c IAR/ARM_CM7/r0p1/portasm.s> # ARMv8-M Ports for IAR EWARM $<$: IAR/ARM_CM23/non_secure/port.c IAR/ARM_CM23/non_secure/portasm.s> $<$: IAR/ARM_CM23/secure/secure_context_port_asm.s IAR/ARM_CM23/secure/secure_context.c IAR/ARM_CM23/secure/secure_heap.c IAR/ARM_CM23/secure/secure_init.c> $<$: IAR/ARM_CM23_NTZ/non_secure/port.c IAR/ARM_CM23_NTZ/non_secure/portasm.s> $<$: IAR/ARM_CM33/non_secure/port.c IAR/ARM_CM33/non_secure/portasm.s> $<$: IAR/ARM_CM33/secure/secure_context_port_asm.s IAR/ARM_CM33/secure/secure_context.c IAR/ARM_CM33/secure/secure_heap.c IAR/ARM_CM33/secure/secure_init.c> $<$: IAR/ARM_CM33_NTZ/non_secure/port.c IAR/ARM_CM33_NTZ/non_secure/portasm.s> # ARMv8.1-M ports for IAR EWARM $<$: IAR/ARM_CM55/non_secure/port.c IAR/ARM_CM55/non_secure/portasm.s> $<$: IAR/ARM_CM55/secure/secure_context_port_asm.s IAR/ARM_CM55/secure/secure_context.c IAR/ARM_CM55/secure/secure_heap.c IAR/ARM_CM55/secure/secure_init.c> $<$: IAR/ARM_CM55_NTZ/non_secure/port.c IAR/ARM_CM55_NTZ/non_secure/portasm.s> $<$: IAR/ARM_CM85/non_secure/port.c IAR/ARM_CM85/non_secure/portasm.s> $<$: IAR/ARM_CM85/secure/secure_context_port_asm.s IAR/ARM_CM85/secure/secure_context.c IAR/ARM_CM85/secure/secure_heap.c IAR/ARM_CM85/secure/secure_init.c> $<$: IAR/ARM_CM85_NTZ/non_secure/port.c IAR/ARM_CM85_NTZ/non_secure/portasm.s> # ARMv7-R Ports for IAR EWARM $<$: IAR/ARM_CRx_No_GIC/port.c IAR/ARM_CRx_No_GIC/portASM.s> # Microchip (formerly Atmel) AVR8 ports for IAR EWAVR $<$: IAR/ATMega323/port.c IAR/ATMega323/portmacro.s90> $<$: IAR/AVR_AVRDx/port.c IAR/AVR_AVRDx/portmacro.s90> $<$: IAR/AVR_Mega0/port.c IAR/AVR_Mega0/portmacro.s90> # Microchip (formerly Atmel) AVR32 port for IAR Embedded Workbench for AVR32 $<$: IAR/AVR32_UC3/exception.s82 IAR/AVR32_UC3/port.c IAR/AVR32_UC3/read.c IAR/AVR32_UC3/write.c> # Texas Instruments MSP430 ports for IAR Embedded Workbench for MSP430 $<$: IAR/MSP430/port.c IAR/MSP430/portext.s43> $<$: IAR/MSP430X/port.c IAR/MSP430X/portext.s43> # RISC-V architecture port for IAR Embedded Workbench for RISC-V $<$: IAR/RISC-V/port.c IAR/RISC-V/portASM.s> # Renesas RL78 port for IAR EWRL78 $<$: IAR/RL78/port.c IAR/RL78/portasm.s87> # Renesas RX architecture ports for IAR EWRX $<$: IAR/RX100/port.c IAR/RX100/port_asm.s> $<$: IAR/RX600/port.c IAR/RX600/port_asm.s> $<$: IAR/RX700v3_DPFPU/port.c> $<$: IAR/RXv2/port.c IAR/RXv2/port_asm.s> # Renesas (formerly NEC) V850ES port for IAR EWV850 $<$: IAR/V850ES/port.c IAR/V850ES/portasm_Fx3.s85> $<$: IAR/V850ES/port.c IAR/V850ES/portasm_Hx2.s85> # ARMv4T ARM7TDMI ports for IAR Embedded Workbench for ARM $<$: IAR/STR71x/port.c IAR/STR71x/portasm.s79> $<$: IAR/STR75x/port.c IAR/STR75x/portasm.s79> $<$: IAR/LPC2000/port.c IAR/LPC2000/portasm.s79> $<$: IAR/AtmelSAM7S64/port.c IAR/AtmelSAM7S64/portasm.s79> # ARMv5TE ARM926 ports for IAR Embedded Workbench for ARM $<$: IAR/STR91x/port.c IAR/STR91x/portasm.s79> $<$: IAR/AtmelSAM9XE/port.c IAR/AtmelSAM9XE/portasm.s79> # ARM Cortex-M4F port for the MikroElektronika MikroC compiler $<$: MikroC/ARM_CM4F/port.c> # Microchip PIC18 8-bit MCU port for MPLAB XC8 $<$: MPLAB/PIC18F/port.c> # Microchip PIC24 16-bit MCU port for MPLAB XC16 $<$: MPLAB/PIC24_dsPIC/port.c MPLAB/PIC24_dsPIC/portasm_PIC24.S> # TODO: What to do with portasm_dsPIC.S ? # Microchip MIPS 32-Bit MCU ports for MPLAB XC32 $<$: MPLAB/PIC32MEC14xx/port.c MPLAB/PIC32MEC14xx/port_asm.S> $<$: MPLAB/PIC32MX/port.c MPLAB/PIC32MX/port_asm.S> $<$: MPLAB/PIC32MZ/port.c MPLAB/PIC32MZ/port_asm.S> # Windows Simulator for Microsoft Visual C Compiler and MinGW GCC $<$: MSVC-MingW/port.c> # 16 bit DOS ports for Open Watcom $<$: oWatcom/16BitDOS/common/portcomn.c oWatcom/16BitDOS/Flsh186/port.c> $<$: oWatcom/16BitDOS/common/portcomn.c oWatcom/16BitDOS/PC/port.c> $<$: Paradigm/Tern_EE/large_untested/port.c> $<$: Paradigm/Tern_EE/small/port.c> # Renesas RX mcu ports for Renesas CC-RX $<$: Renesas/RX100/port.c Renesas/RX100/port_asm.src> $<$: Renesas/RX200/port.c Renesas/RX200/port_asm.src> $<$: Renesas/RX600/port.c Renesas/RX600/port_asm.src> $<$: Renesas/RX600v2/port.c Renesas/RX600v2/port_asm.src> $<$: Renesas/RX700v3_DPFPU/port.c Renesas/RX700v3_DPFPU/port_asm.src> # Renesas (formerly Hitach) SHA2 SuperH port for the Renesas SH C Compiler $<$: Renesas/SH2A_FPU/port.c Renesas/SH2A_FPU/portasm.src> # Texas Instruments MSP430 port for Rowley CrossWorks $<$: Rowley/MSP430F449/port.c Rowley/MSP430F449/portext.asm> # ARMv7-A Cortex-A9 port for ARM RVDS / armcc $<$: RVDS/ARM_CA9/port.c RVDS/ARM_CA9/portASM.s> # ARMv6-M port for ARM RVDS / armcc $<$: RVDS/ARM_CM0/port.c> # ARMv7-M port for ARM RVDS / armcc $<$: RVDS/ARM_CM3/port.c> # ARMv7E-M ports for ARM RVDS / armcc $<$: RVDS/ARM_CM4_MPU/port.c> $<$: RVDS/ARM_CM4F/port.c> $<$: RVDS/ARM_CM7/r0p1/port.c> # ARMv4T / ARM7TDMI LPC21XX port for ARM RVDS / armcc $<$: RVDS/ARM7_LPC21xx/port.c RVDS/ARM7_LPC21xx/portASM.s> # Cygnal c8051 port for SDCC (Small Device C Compiler) $<$: SDCC/Cygnal/port.c> # Infineon (formerly Fujitsu, Spansion, Cypress) MB9x ports for Softune C Compiler $<$: Softune/MB91460/__STD_LIB_sbrk.c Softune/MB91460/port.c> $<$: Softune/MB96340/__STD_LIB_sbrk.c Softune/MB96340/port.c> # ARMv7E-M (Cortex-M4F) port for TASKING VX-toolset for ARM $<$: Tasking/ARM_CM4F/port.c Tasking/ARM_CM4F/port_asm.asm> # Port for C-SKY T-HEAD CK802 $<$: ThirdParty/CDK/T-HEAD_CK802/port.c ThirdParty/CDK/T-HEAD_CK802/portasm.S> # Tensilica Xtensa port for XCC $<$: ThirdParty/XCC/Xtensa/port.c ThirdParty/XCC/Xtensa/portasm.S ThirdParty/XCC/Xtensa/portclib.c ThirdParty/XCC/Xtensa/xtensa_context.S ThirdParty/XCC/Xtensa/xtensa_init.c ThirdParty/XCC/Xtensa/xtensa_intr_asm.S ThirdParty/XCC/Xtensa/xtensa_intr.c ThirdParty/XCC/Xtensa/xtensa_overlay_os_hook.c ThirdParty/XCC/Xtensa/xtensa_vectors.S> # Microchip PIC18 port for WIZ-C $<$: WizC/PIC18/port.c WizC/PIC18/Drivers/Tick/isrTick.c WizC/PIC18/Drivers/Tick/Tick.c> ) if( FREERTOS_PORT MATCHES "GCC_ARM_CM(3|4)_MPU" OR FREERTOS_PORT STREQUAL "IAR_ARM_CM4F_MPU" OR FREERTOS_PORT STREQUAL "RVDS_ARM_CM4_MPU" OR FREERTOS_PORT MATCHES "GCC_ARM_CM(23|33|55|85)_NTZ_NONSECURE" OR FREERTOS_PORT MATCHES "GCC_ARM_CM(23|33|55|85)_NONSECURE" OR FREERTOS_PORT MATCHES "GCC_ARM_CM(33|55|85)_TFM" OR FREERTOS_PORT MATCHES "IAR_ARM_CM(23|33|55|85)_NTZ_NONSECURE" OR FREERTOS_PORT MATCHES "IAR_ARM_CM(23|33|55|85)_NONSECURE" ) target_sources(freertos_kernel_port PRIVATE Common/mpu_wrappers.c) endif() target_include_directories(freertos_kernel_port PUBLIC # 16-Bit DOS ports for BCC $<$: ${CMAKE_CURRENT_LIST_DIR}/BCC/16BitDOS/common ${CMAKE_CURRENT_LIST_DIR}/BCC/16BitDOS/Flsh186> $<$: ${CMAKE_CURRENT_LIST_DIR}/BCC/16BitDOS/common ${CMAKE_CURRENT_LIST_DIR}/BCC/16BitDOS/PC> # ARMv7-M port for Texas Instruments Code Composer Studio $<$:${CMAKE_CURRENT_LIST_DIR}/CCS/ARM_CM3> # ARMv7E-M port for Texas Instruments Code Composer Studio $<$:${CMAKE_CURRENT_LIST_DIR}/CCS/ARM_CM4F> # ARMv7-R port for Texas Instruments Code Composer Studio $<$:${CMAKE_CURRENT_LIST_DIR}/CCS/ARM_Cortex-R4> # Texas Instruments MSP430 port for Texas Instruments Code Composer Studio $<$:${CMAKE_CURRENT_LIST_DIR}/CCS/MSP430X> # NXP (formerly Motorola, Freescale) Cold Fire and 68HCS12 ports for Code Warrior $<$:${CMAKE_CURRENT_LIST_DIR}/CodeWarrior/ColdFire_V1> $<$:${CMAKE_CURRENT_LIST_DIR}/CodeWarrior/ColdFire_V2> $<$:${CMAKE_CURRENT_LIST_DIR}/CodeWarrior/HCS12> # ARMv7-A port for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CA9> # ARMv8-A ports for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CA53_64_BIT> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CA53_64_BIT_SRE> # ARMv6-M port for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM0> # ARMv6-M / Cortex-M0 Raspberry PI RP2040 port for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/ThirdParty/GCC/RP2040/include> # ARMv7-M ports for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM3> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM3_MPU> # ARMv7E-M ports for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM4_MPU> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM4F> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM7/r0p1> # ARMv8-M ports for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM23/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM23/secure> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM23_NTZ/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM33/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM33/secure> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM33_NTZ/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM33_NTZ/non_secure> # ARMv8.1-M ports for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM55/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM55/secure> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM55_NTZ/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85_NTZ/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85/secure> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85_NTZ/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85_NTZ/non_secure> # ARMv7-R ports for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CR5> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CRx_No_GIC> # ARMv4T ARM7TDMI ports for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM7_AT91FR40008> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM7_AT91SAM7S> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM7_LPC2000> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM7_LPC23xx> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/STR75x> # Microchip (formerly Ateml) AVR8 ports for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ATMega323> $<$:${CMAKE_CURRENT_LIST_DIR}/ThirdParty/GCC/ATmega> $<$:${CMAKE_CURRENT_LIST_DIR}/ThirdParty/Partner-Supported-Ports/GCC/AVR_AVRDx> $<$:${CMAKE_CURRENT_LIST_DIR}/ThirdParty/Partner-Supported-Ports/GCC/AVR_Mega0> # Microchip (formerly Ateml) AVR32 port for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/AVR32_UC3> # NXP (formerly Motorola, Freescale) Cold Fire and 68HCS12 ports for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ColdFire_V2> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/HCS12> # Cortus APS3 soft core port for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/CORTUS_APS3> # Renesas (formerly Hitach) H8S port for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/H8S2329> # x86 / IA32 flat memory model port for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/IA32_flat> # Intel (formerly Altera) NIOS II soft core port for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/NiosII> # Texas Instruments MSP430 port for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/MSP430F449> # Xilinx MicroBlaze soft core ports for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/MicroBlaze> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/MicroBlazeV8> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/MicroBlazeV9> # Xilinx PCC4XX soft core ports for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/PPC405_Xilinx> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/PPC440_Xilinx> # RISC-V architecture ports for GCC $<$: ${CMAKE_CURRENT_LIST_DIR}/GCC/RISC-V ${CMAKE_CURRENT_LIST_DIR}/GCC/RISC-V/chip_specific_extensions/RISCV_MTIME_CLINT_no_extensions> $<$: ${CMAKE_CURRENT_LIST_DIR}/GCC/RISC-V ${CMAKE_CURRENT_LIST_DIR}/GCC/RISC-V/chip_specific_extensions/Pulpino_Vega_RV32M1RM> # Renesas RL78 port for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/RL78> # Renesas RX architecture ports for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/RX100> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/RX200> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/RX600> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/RX600v2> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/RX700v3_DPFPU> # Infineon TriCore 1782 port for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/TriCore_1782> # Synopsys ARC architecture ports for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/ThirdParty/GCC/ARC_EM_HS> $<$:${CMAKE_CURRENT_LIST_DIR}/ThirdParty/GCC/ARC_v1> # Posix Simulator port for GCC $<$: ${CMAKE_CURRENT_LIST_DIR}/ThirdParty/GCC/Posix ${CMAKE_CURRENT_LIST_DIR}/ThirdParty/GCC/Posix/utils> # Xtensa LX / Espressif ESP32 port for GCC $<$: ${CMAKE_CURRENT_LIST_DIR}/ThirdParty/GCC/Xtensa_ESP32 ${CMAKE_CURRENT_LIST_DIR}/ThirdParty/GCC/Xtensa_ESP32/include> # Renesas (formerly NEC) 78K port for IAR EW78K $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/78K0R> # ARMv7-A ports for IAR EWARM $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CA5_No_GIC> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CA9> # ARMv6-M port for IAR EWARM $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM0> # ARMv7-M port for IAR EWARM $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM3> # ARMv7E-M ports for IAR EWARM $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM4F> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM4F_MPU> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM7/r0p1> # ARMv8-M Ports for IAR EWARM $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM23/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM23/secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM23_NTZ/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM33/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM33/secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM33_NTZ/non_secure> # ARMv8.1-M ports for IAR EWARM $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55/secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55_NTZ/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85/secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85_NTZ/non_secure> # ARMv7-R Ports for IAR EWARM $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CRx_No_GIC> # ARMv4T ARM7TDMI ports for IAR Embedded Workbench for ARM $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/STR71x> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/STR75x> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/LPC2000> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/AtmelSAM7S64> # ARMv5TE ARM926 ports for IAR Embedded Workbench for ARM $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/STR91x> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/AtmelSAM9XE> # Microchip (formerly Atmel) AVR8 ports for IAR EWAVR $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ATMega323> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/AVR_AVRDx> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/AVR_Mega0> # Microchip (formerly Atmel) AVR32 port for IAR Embedded Workbench for AVR32 $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/AVR32_UC3> # Texas Instruments MSP430 ports for IAR Embedded Workbench for MSP430 $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/MSP430> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/MSP430X> # RISC-V architecture port for IAR Embedded Workbench for RISC-V $<$: ${CMAKE_CURRENT_LIST_DIR}/IAR/RISC-V ${CMAKE_CURRENT_LIST_DIR}/IAR/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions> # Renesas RL78 port for IAR EWRL78 $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/RL78> # Renesas RX architecture ports for IAR EWRX $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/RX100> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/RX600> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/RX700v3_DPFPU> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/RXv2> # Renesas (formerly NEC) V850ES port for IAR EWV850 $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/V850ES> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/V850ES> # ARM Cortex-M4F port for the MikroElektronika MikroC compiler $<$:${CMAKE_CURRENT_LIST_DIR}/MikroC/ARM_CM4F> # Microchip PIC18 8-bit MCU port for MPLAB XC8 $<$:${CMAKE_CURRENT_LIST_DIR}/MPLAB/PIC18F> # Microchip PIC24 16-bit MCU port for MPLAB XC16 $<$:${CMAKE_CURRENT_LIST_DIR}/MPLAB/PIC24_dsPIC> # Microchip MIPS 32-Bit MCU ports for MPLAB XC32 $<$:${CMAKE_CURRENT_LIST_DIR}/MPLAB/PIC32MEC14xx> $<$:${CMAKE_CURRENT_LIST_DIR}/MPLAB/PIC32MX> $<$:${CMAKE_CURRENT_LIST_DIR}/MPLAB/PIC32MZ> # Windows Simulator for Microsoft Visual C Compiler and MinGW GCC $<$:${CMAKE_CURRENT_LIST_DIR}/MSVC-MingW> # 16 bit DOS ports for Open Watcom $<$: ${CMAKE_CURRENT_LIST_DIR}/oWatcom/16BitDOS/common ${CMAKE_CURRENT_LIST_DIR}/oWatcom/16BitDOS/Flsh186> $<$: ${CMAKE_CURRENT_LIST_DIR}/oWatcom/16BitDOS/common ${CMAKE_CURRENT_LIST_DIR}/oWatcom/16BitDOS/PC> $<$:${CMAKE_CURRENT_LIST_DIR}/Paradigm/Tern_EE/large_untested> $<$:${CMAKE_CURRENT_LIST_DIR}/Paradigm/Tern_EE/small> # Renesas RX mcu ports for Renesas CC-RX $<$:${CMAKE_CURRENT_LIST_DIR}/Renesas/RX100> $<$:${CMAKE_CURRENT_LIST_DIR}/Renesas/RX200> $<$:${CMAKE_CURRENT_LIST_DIR}/Renesas/RX600> $<$:${CMAKE_CURRENT_LIST_DIR}/Renesas/RX600v2> $<$:${CMAKE_CURRENT_LIST_DIR}/Renesas/RX700v3_DPFPU> # Renesas (formerly Hitach) SHA2 SuperH port for the Renesas SH C Compiler $<$:${CMAKE_CURRENT_LIST_DIR}/Renesas/SH2A_FPU> # Texas Instruments MSP430 port for Rowley CrossWorks $<$:${CMAKE_CURRENT_LIST_DIR}/Rowley/MSP430F449> # ARMv7-A Cortex-A9 port for ARM RVDS / armcc $<$:${CMAKE_CURRENT_LIST_DIR}/RVDS/ARM_CA9> # ARMv6-M port for ARM RVDS / armcc $<$:${CMAKE_CURRENT_LIST_DIR}/RVDS/ARM_CM0> # ARMv7-M port for ARM RVDS / armcc $<$:${CMAKE_CURRENT_LIST_DIR}/RVDS/ARM_CM3> # ARMv7E-M ports for ARM RVDS / armcc $<$:${CMAKE_CURRENT_LIST_DIR}/RVDS/ARM_CM4_MPU> $<$:${CMAKE_CURRENT_LIST_DIR}/RVDS/ARM_CM4F> $<$:${CMAKE_CURRENT_LIST_DIR}/RVDS/ARM_CM7/r0p1> # ARMv4T / ARM7TDMI LPC21XX port for ARM RVDS / armcc $<$:${CMAKE_CURRENT_LIST_DIR}/RVDS/ARM7_LPC21xx> # Cygnal c8051 port for SDCC (Small Device C Compiler) $<$:${CMAKE_CURRENT_LIST_DIR}/SDCC/Cygnal> # Infineon (formerly Fujitsu, Spansion, Cypress) MB9x ports for Softune C Compiler $<$:${CMAKE_CURRENT_LIST_DIR}/Softune/MB91460> $<$:${CMAKE_CURRENT_LIST_DIR}/Softune/MB96340> # ARMv7E-M (Cortex-M4F) port for TASKING VX-toolset for ARM $<$:${CMAKE_CURRENT_LIST_DIR}/Tasking/ARM_CM4F> # Port for C-SKY T-HEAD CK802 $<$:${CMAKE_CURRENT_LIST_DIR}/ThirdParty/CDK/T-HEAD_CK802> # Tensilica Xtensa port for XCC $<$:${CMAKE_CURRENT_LIST_DIR}/ThirdParty/XCC/Xtensa> # Microchip PIC18 port for WIZ-C $<$:${CMAKE_CURRENT_LIST_DIR}/WizC/PIC18> ) target_link_libraries(freertos_kernel_port PUBLIC $<$:pico_base_headers> $<$:idf::esp32> PRIVATE freertos_kernel "$<$:hardware_clocks;hardware_exception>" $<$:winmm> # Windows library which implements timers ) ================================================ FILE: FreeRTOS-comparison/portable/Common/mpu_wrappers.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* * Implementation of the wrapper functions used to raise the processor privilege * before calling a standard FreeRTOS API function. */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "timers.h" #include "event_groups.h" #include "stream_buffer.h" #include "mpu_prototypes.h" #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*-----------------------------------------------------------*/ #if ( portUSING_MPU_WRAPPERS == 1 ) #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void * pvParameters, UBaseType_t uxPriority, TaskHandle_t * pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); uxPriority = uxPriority & ~( portPRIVILEGE_BIT ); portMEMORY_BARRIER(); xReturn = xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ); } return xReturn; } #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ /*-----------------------------------------------------------*/ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) /* FREERTOS_SYSTEM_CALL */ { TaskHandle_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); uxPriority = uxPriority & ~( portPRIVILEGE_BIT ); portMEMORY_BARRIER(); xReturn = xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); } return xReturn; } #endif /* configSUPPORT_STATIC_ALLOCATION */ /*-----------------------------------------------------------*/ #if ( INCLUDE_vTaskDelete == 1 ) void MPU_vTaskDelete( TaskHandle_t pxTaskToDelete ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vTaskDelete( pxTaskToDelete ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vTaskDelete( pxTaskToDelete ); } } #endif /* if ( INCLUDE_vTaskDelete == 1 ) */ /*-----------------------------------------------------------*/ #if ( INCLUDE_xTaskDelayUntil == 1 ) BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, TickType_t xTimeIncrement ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ); } return xReturn; } #endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ /*-----------------------------------------------------------*/ #if ( INCLUDE_xTaskAbortDelay == 1 ) BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTaskAbortDelay( xTask ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTaskAbortDelay( xTask ); } return xReturn; } #endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ /*-----------------------------------------------------------*/ #if ( INCLUDE_vTaskDelay == 1 ) void MPU_vTaskDelay( TickType_t xTicksToDelay ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vTaskDelay( xTicksToDelay ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vTaskDelay( xTicksToDelay ); } } #endif /* if ( INCLUDE_vTaskDelay == 1 ) */ /*-----------------------------------------------------------*/ #if ( INCLUDE_uxTaskPriorityGet == 1 ) UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t pxTask ) /* FREERTOS_SYSTEM_CALL */ { UBaseType_t uxReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); uxReturn = uxTaskPriorityGet( pxTask ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { uxReturn = uxTaskPriorityGet( pxTask ); } return uxReturn; } #endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ /*-----------------------------------------------------------*/ #if ( INCLUDE_vTaskPrioritySet == 1 ) void MPU_vTaskPrioritySet( TaskHandle_t pxTask, UBaseType_t uxNewPriority ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vTaskPrioritySet( pxTask, uxNewPriority ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vTaskPrioritySet( pxTask, uxNewPriority ); } } #endif /* if ( INCLUDE_vTaskPrioritySet == 1 ) */ /*-----------------------------------------------------------*/ #if ( INCLUDE_eTaskGetState == 1 ) eTaskState MPU_eTaskGetState( TaskHandle_t pxTask ) /* FREERTOS_SYSTEM_CALL */ { eTaskState eReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); eReturn = eTaskGetState( pxTask ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { eReturn = eTaskGetState( pxTask ); } return eReturn; } #endif /* if ( INCLUDE_eTaskGetState == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_TRACE_FACILITY == 1 ) void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t * pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vTaskGetInfo( xTask, pxTaskStatus, xGetFreeStackSpace, eState ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vTaskGetInfo( xTask, pxTaskStatus, xGetFreeStackSpace, eState ); } } #endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ /*-----------------------------------------------------------*/ #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ { TaskHandle_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTaskGetIdleTaskHandle(); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTaskGetIdleTaskHandle(); } return xReturn; } #endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ /*-----------------------------------------------------------*/ #if ( INCLUDE_vTaskSuspend == 1 ) void MPU_vTaskSuspend( TaskHandle_t pxTaskToSuspend ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vTaskSuspend( pxTaskToSuspend ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vTaskSuspend( pxTaskToSuspend ); } } #endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ /*-----------------------------------------------------------*/ #if ( INCLUDE_vTaskSuspend == 1 ) void MPU_vTaskResume( TaskHandle_t pxTaskToResume ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vTaskResume( pxTaskToResume ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vTaskResume( pxTaskToResume ); } } #endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ /*-----------------------------------------------------------*/ void MPU_vTaskSuspendAll( void ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vTaskSuspendAll(); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vTaskSuspendAll(); } } /*-----------------------------------------------------------*/ BaseType_t MPU_xTaskResumeAll( void ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTaskResumeAll(); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTaskResumeAll(); } return xReturn; } /*-----------------------------------------------------------*/ TickType_t MPU_xTaskGetTickCount( void ) /* FREERTOS_SYSTEM_CALL */ { TickType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTaskGetTickCount(); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTaskGetTickCount(); } return xReturn; } /*-----------------------------------------------------------*/ UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* FREERTOS_SYSTEM_CALL */ { UBaseType_t uxReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); uxReturn = uxTaskGetNumberOfTasks(); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { uxReturn = uxTaskGetNumberOfTasks(); } return uxReturn; } /*-----------------------------------------------------------*/ char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* FREERTOS_SYSTEM_CALL */ { char * pcReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); pcReturn = pcTaskGetName( xTaskToQuery ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { pcReturn = pcTaskGetName( xTaskToQuery ); } return pcReturn; } /*-----------------------------------------------------------*/ #if ( INCLUDE_xTaskGetHandle == 1 ) TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) /* FREERTOS_SYSTEM_CALL */ { TaskHandle_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTaskGetHandle( pcNameToQuery ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTaskGetHandle( pcNameToQuery ); } return xReturn; } #endif /* if ( INCLUDE_xTaskGetHandle == 1 ) */ /*-----------------------------------------------------------*/ #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) void MPU_vTaskList( char * pcWriteBuffer ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vTaskList( pcWriteBuffer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vTaskList( pcWriteBuffer ); } } #endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) void MPU_vTaskGetRunTimeStats( char * pcWriteBuffer ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vTaskGetRunTimeStats( pcWriteBuffer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vTaskGetRunTimeStats( pcWriteBuffer ); } } #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* FREERTOS_SYSTEM_CALL */ { configRUN_TIME_COUNTER_TYPE xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = ulTaskGetIdleRunTimePercent(); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = ulTaskGetIdleRunTimePercent(); } return xReturn; } #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* FREERTOS_SYSTEM_CALL */ { configRUN_TIME_COUNTER_TYPE xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = ulTaskGetIdleRunTimeCounter(); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = ulTaskGetIdleRunTimeCounter(); } return xReturn; } #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( configUSE_APPLICATION_TASK_TAG == 1 ) void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxTagValue ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vTaskSetApplicationTaskTag( xTask, pxTagValue ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vTaskSetApplicationTaskTag( xTask, pxTagValue ); } } #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_APPLICATION_TASK_TAG == 1 ) TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ { TaskHookFunction_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTaskGetApplicationTaskTag( xTask ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTaskGetApplicationTaskTag( xTask ); } return xReturn; } #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ /*-----------------------------------------------------------*/ #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void * pvValue ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vTaskSetThreadLocalStoragePointer( xTaskToSet, xIndex, pvValue ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vTaskSetThreadLocalStoragePointer( xTaskToSet, xIndex, pvValue ); } } #endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ /*-----------------------------------------------------------*/ #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) /* FREERTOS_SYSTEM_CALL */ { void * pvReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); pvReturn = pvTaskGetThreadLocalStoragePointer( xTaskToQuery, xIndex ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { pvReturn = pvTaskGetThreadLocalStoragePointer( xTaskToQuery, xIndex ); } return pvReturn; } #endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_APPLICATION_TASK_TAG == 1 ) BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void * pvParameter ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTaskCallApplicationTaskHook( xTask, pvParameter ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTaskCallApplicationTaskHook( xTask, pvParameter ); } return xReturn; } #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * pxTaskStatusArray, UBaseType_t uxArraySize, configRUN_TIME_COUNTER_TYPE * pulTotalRunTime ) /* FREERTOS_SYSTEM_CALL */ { UBaseType_t uxReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); uxReturn = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, pulTotalRunTime ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { uxReturn = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, pulTotalRunTime ); } return uxReturn; } #endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ /*-----------------------------------------------------------*/ BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTaskCatchUpTicks( xTicksToCatchUp ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTaskCatchUpTicks( xTicksToCatchUp ); } return xReturn; } /*-----------------------------------------------------------*/ #if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ { UBaseType_t uxReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); uxReturn = uxTaskGetStackHighWaterMark( xTask ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { uxReturn = uxTaskGetStackHighWaterMark( xTask ); } return uxReturn; } #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ /*-----------------------------------------------------------*/ #if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ { configSTACK_DEPTH_TYPE uxReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); uxReturn = uxTaskGetStackHighWaterMark2( xTask ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { uxReturn = uxTaskGetStackHighWaterMark2( xTask ); } return uxReturn; } #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ /*-----------------------------------------------------------*/ #if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ { TaskHandle_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTaskGetCurrentTaskHandle(); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTaskGetCurrentTaskHandle(); } return xReturn; } #endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( INCLUDE_xTaskGetSchedulerState == 1 ) BaseType_t MPU_xTaskGetSchedulerState( void ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTaskGetSchedulerState(); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTaskGetSchedulerState(); } return xReturn; } #endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ /*-----------------------------------------------------------*/ void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vTaskSetTimeOutState( pxTimeOut ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vTaskSetTimeOutState( pxTimeOut ); } } /*-----------------------------------------------------------*/ BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTaskCheckForTimeOut( pxTimeOut, pxTicksToWait ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTaskCheckForTimeOut( pxTimeOut, pxTicksToWait ); } return xReturn; } /*-----------------------------------------------------------*/ #if ( configUSE_TASK_NOTIFICATIONS == 1 ) BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t * pulPreviousNotificationValue ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTaskGenericNotify( xTaskToNotify, uxIndexToNotify, ulValue, eAction, pulPreviousNotificationValue ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTaskGenericNotify( xTaskToNotify, uxIndexToNotify, ulValue, eAction, pulPreviousNotificationValue ); } return xReturn; } #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_TASK_NOTIFICATIONS == 1 ) BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t * pulNotificationValue, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTaskGenericNotifyWait( uxIndexToWaitOn, ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTaskGenericNotifyWait( uxIndexToWaitOn, ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ); } return xReturn; } #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_TASK_NOTIFICATIONS == 1 ) uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ { uint32_t ulReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); ulReturn = ulTaskGenericNotifyTake( uxIndexToWaitOn, xClearCountOnExit, xTicksToWait ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { ulReturn = ulTaskGenericNotifyTake( uxIndexToWaitOn, xClearCountOnExit, xTicksToWait ); } return ulReturn; } #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_TASK_NOTIFICATIONS == 1 ) BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTaskGenericNotifyStateClear( xTask, uxIndexToClear ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTaskGenericNotifyStateClear( xTask, uxIndexToClear ); } return xReturn; } #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_TASK_NOTIFICATIONS == 1 ) uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear ) /* FREERTOS_SYSTEM_CALL */ { uint32_t ulReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); ulReturn = ulTaskGenericNotifyValueClear( xTask, uxIndexToClear, ulBitsToClear ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { ulReturn = ulTaskGenericNotifyValueClear( xTask, uxIndexToClear, ulBitsToClear ); } return ulReturn; } #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ /*-----------------------------------------------------------*/ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) QueueHandle_t MPU_xQueueGenericCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize, uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */ { QueueHandle_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueueGenericCreate( uxQueueLength, uxItemSize, ucQueueType ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueueGenericCreate( uxQueueLength, uxItemSize, ucQueueType ); } return xReturn; } #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ /*-----------------------------------------------------------*/ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t * pucQueueStorage, StaticQueue_t * pxStaticQueue, const uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */ { QueueHandle_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueueGenericCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxStaticQueue, ucQueueType ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueueGenericCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxStaticQueue, ucQueueType ); } return xReturn; } #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ /*-----------------------------------------------------------*/ BaseType_t MPU_xQueueGenericReset( QueueHandle_t pxQueue, BaseType_t xNewQueue ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueueGenericReset( pxQueue, xNewQueue ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueueGenericReset( pxQueue, xNewQueue ); } return xReturn; } /*-----------------------------------------------------------*/ BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, BaseType_t xCopyPosition ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, xCopyPosition ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, xCopyPosition ); } return xReturn; } /*-----------------------------------------------------------*/ UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t pxQueue ) /* FREERTOS_SYSTEM_CALL */ { UBaseType_t uxReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); uxReturn = uxQueueMessagesWaiting( pxQueue ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { uxReturn = uxQueueMessagesWaiting( pxQueue ); } return uxReturn; } /*-----------------------------------------------------------*/ UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ { UBaseType_t uxReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); uxReturn = uxQueueSpacesAvailable( xQueue ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { uxReturn = uxQueueSpacesAvailable( xQueue ); } return uxReturn; } /*-----------------------------------------------------------*/ BaseType_t MPU_xQueueReceive( QueueHandle_t pxQueue, void * const pvBuffer, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueueReceive( pxQueue, pvBuffer, xTicksToWait ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueueReceive( pxQueue, pvBuffer, xTicksToWait ); } return xReturn; } /*-----------------------------------------------------------*/ BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueuePeek( xQueue, pvBuffer, xTicksToWait ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueuePeek( xQueue, pvBuffer, xTicksToWait ); } return xReturn; } /*-----------------------------------------------------------*/ BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueueSemaphoreTake( xQueue, xTicksToWait ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueueSemaphoreTake( xQueue, xTicksToWait ); } return xReturn; } /*-----------------------------------------------------------*/ #if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* FREERTOS_SYSTEM_CALL */ { void * xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueueGetMutexHolder( xSemaphore ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueueGetMutexHolder( xSemaphore ); } return xReturn; } #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */ { QueueHandle_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueueCreateMutex( ucQueueType ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueueCreateMutex( ucQueueType ); } return xReturn; } #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t * pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */ { QueueHandle_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueueCreateMutexStatic( ucQueueType, pxStaticQueue ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueueCreateMutexStatic( ucQueueType, pxStaticQueue ); } return xReturn; } #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) QueueHandle_t MPU_xQueueCreateCountingSemaphore( UBaseType_t uxCountValue, UBaseType_t uxInitialCount ) /* FREERTOS_SYSTEM_CALL */ { QueueHandle_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueueCreateCountingSemaphore( uxCountValue, uxInitialCount ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueueCreateCountingSemaphore( uxCountValue, uxInitialCount ); } return xReturn; } #endif /* if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t * pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */ { QueueHandle_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueueCreateCountingSemaphoreStatic( uxMaxCount, uxInitialCount, pxStaticQueue ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueueCreateCountingSemaphoreStatic( uxMaxCount, uxInitialCount, pxStaticQueue ); } return xReturn; } #endif /* if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( configUSE_RECURSIVE_MUTEXES == 1 ) BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xBlockTime ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueueTakeMutexRecursive( xMutex, xBlockTime ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueueTakeMutexRecursive( xMutex, xBlockTime ); } return xReturn; } #endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_RECURSIVE_MUTEXES == 1 ) BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t xMutex ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueueGiveMutexRecursive( xMutex ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueueGiveMutexRecursive( xMutex ); } return xReturn; } #endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ /*-----------------------------------------------------------*/ #if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) QueueSetHandle_t MPU_xQueueCreateSet( UBaseType_t uxEventQueueLength ) /* FREERTOS_SYSTEM_CALL */ { QueueSetHandle_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueueCreateSet( uxEventQueueLength ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueueCreateSet( uxEventQueueLength ); } return xReturn; } #endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( configUSE_QUEUE_SETS == 1 ) QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t xBlockTimeTicks ) /* FREERTOS_SYSTEM_CALL */ { QueueSetMemberHandle_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueueSelectFromSet( xQueueSet, xBlockTimeTicks ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueueSelectFromSet( xQueueSet, xBlockTimeTicks ); } return xReturn; } #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_QUEUE_SETS == 1 ) BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueueAddToSet( xQueueOrSemaphore, xQueueSet ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueueAddToSet( xQueueOrSemaphore, xQueueSet ); } return xReturn; } #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_QUEUE_SETS == 1 ) BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xQueueRemoveFromSet( xQueueOrSemaphore, xQueueSet ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xQueueRemoveFromSet( xQueueOrSemaphore, xQueueSet ); } return xReturn; } #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ /*-----------------------------------------------------------*/ #if configQUEUE_REGISTRY_SIZE > 0 void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char * pcName ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vQueueAddToRegistry( xQueue, pcName ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vQueueAddToRegistry( xQueue, pcName ); } } #endif /* if configQUEUE_REGISTRY_SIZE > 0 */ /*-----------------------------------------------------------*/ #if configQUEUE_REGISTRY_SIZE > 0 void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vQueueUnregisterQueue( xQueue ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vQueueUnregisterQueue( xQueue ); } } #endif /* if configQUEUE_REGISTRY_SIZE > 0 */ /*-----------------------------------------------------------*/ #if configQUEUE_REGISTRY_SIZE > 0 const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ { const char * pcReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); pcReturn = pcQueueGetName( xQueue ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { pcReturn = pcQueueGetName( xQueue ); } return pcReturn; } #endif /* if configQUEUE_REGISTRY_SIZE > 0 */ /*-----------------------------------------------------------*/ void MPU_vQueueDelete( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vQueueDelete( xQueue ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vQueueDelete( xQueue ); } } /*-----------------------------------------------------------*/ #if ( configUSE_TIMERS == 1 ) void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ { void * pvReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); pvReturn = pvTimerGetTimerID( xTimer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { pvReturn = pvTimerGetTimerID( xTimer ); } return pvReturn; } #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void * pvNewID ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vTimerSetTimerID( xTimer, pvNewID ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vTimerSetTimerID( xTimer, pvNewID ); } } #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_TIMERS == 1 ) BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTimerIsTimerActive( xTimer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTimerIsTimerActive( xTimer ); } return xReturn; } #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_TIMERS == 1 ) TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ { TaskHandle_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTimerGetTimerDaemonTaskHandle(); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTimerGetTimerDaemonTaskHandle(); } return xReturn; } #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vTimerSetReloadMode( xTimer, uxAutoReload ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vTimerSetReloadMode( xTimer, uxAutoReload ); } } #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_TIMERS == 1 ) UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) { UBaseType_t uxReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); uxReturn = uxTimerGetReloadMode( xTimer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { uxReturn = uxTimerGetReloadMode( xTimer ); } return uxReturn; } #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_TIMERS == 1 ) const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ { const char * pcReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); pcReturn = pcTimerGetName( xTimer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { pcReturn = pcTimerGetName( xTimer ); } return pcReturn; } #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_TIMERS == 1 ) TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ { TickType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTimerGetPeriod( xTimer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTimerGetPeriod( xTimer ); } return xReturn; } #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_TIMERS == 1 ) TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ { TickType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTimerGetExpiryTime( xTimer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTimerGetExpiryTime( xTimer ); } return xReturn; } #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ #if ( configUSE_TIMERS == 1 ) BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xTimerGenericCommand( xTimer, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xTimerGenericCommand( xTimer, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ); } return xReturn; } #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) EventGroupHandle_t MPU_xEventGroupCreate( void ) /* FREERTOS_SYSTEM_CALL */ { EventGroupHandle_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xEventGroupCreate(); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xEventGroupCreate(); } return xReturn; } #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ /*-----------------------------------------------------------*/ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) /* FREERTOS_SYSTEM_CALL */ { EventGroupHandle_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xEventGroupCreateStatic( pxEventGroupBuffer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xEventGroupCreateStatic( pxEventGroupBuffer ); } return xReturn; } #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ /*-----------------------------------------------------------*/ EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ { EventBits_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait ); } return xReturn; } /*-----------------------------------------------------------*/ EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) /* FREERTOS_SYSTEM_CALL */ { EventBits_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xEventGroupClearBits( xEventGroup, uxBitsToClear ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xEventGroupClearBits( xEventGroup, uxBitsToClear ); } return xReturn; } /*-----------------------------------------------------------*/ EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) /* FREERTOS_SYSTEM_CALL */ { EventBits_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xEventGroupSetBits( xEventGroup, uxBitsToSet ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xEventGroupSetBits( xEventGroup, uxBitsToSet ); } return xReturn; } /*-----------------------------------------------------------*/ EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ { EventBits_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xEventGroupSync( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xEventGroupSync( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); } return xReturn; } /*-----------------------------------------------------------*/ void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vEventGroupDelete( xEventGroup ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vEventGroupDelete( xEventGroup ); } } /*-----------------------------------------------------------*/ size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void * pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ { size_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xStreamBufferSend( xStreamBuffer, pvTxData, xDataLengthBytes, xTicksToWait ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xStreamBufferSend( xStreamBuffer, pvTxData, xDataLengthBytes, xTicksToWait ); } return xReturn; } /*-----------------------------------------------------------*/ size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ { size_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xStreamBufferNextMessageLengthBytes( xStreamBuffer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xStreamBufferNextMessageLengthBytes( xStreamBuffer ); } return xReturn; } /*-----------------------------------------------------------*/ size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void * pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ { size_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xStreamBufferReceive( xStreamBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xStreamBufferReceive( xStreamBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ); } return xReturn; } /*-----------------------------------------------------------*/ void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); vStreamBufferDelete( xStreamBuffer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { vStreamBufferDelete( xStreamBuffer ); } } /*-----------------------------------------------------------*/ BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xStreamBufferIsFull( xStreamBuffer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xStreamBufferIsFull( xStreamBuffer ); } return xReturn; } /*-----------------------------------------------------------*/ BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xStreamBufferIsEmpty( xStreamBuffer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xStreamBufferIsEmpty( xStreamBuffer ); } return xReturn; } /*-----------------------------------------------------------*/ BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xStreamBufferReset( xStreamBuffer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xStreamBufferReset( xStreamBuffer ); } return xReturn; } /*-----------------------------------------------------------*/ size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ { size_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xStreamBufferSpacesAvailable( xStreamBuffer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xStreamBufferSpacesAvailable( xStreamBuffer ); } return xReturn; } /*-----------------------------------------------------------*/ size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ { size_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xStreamBufferBytesAvailable( xStreamBuffer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xStreamBufferBytesAvailable( xStreamBuffer ); } return xReturn; } /*-----------------------------------------------------------*/ BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) /* FREERTOS_SYSTEM_CALL */ { BaseType_t xReturn; if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xStreamBufferSetTriggerLevel( xStreamBuffer, xTriggerLevel ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xStreamBufferSetTriggerLevel( xStreamBuffer, xTriggerLevel ); } return xReturn; } /*-----------------------------------------------------------*/ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) /* FREERTOS_SYSTEM_CALL */ { StreamBufferHandle_t xReturn; /** * Streambuffer application level callback functionality is disabled for MPU * enabled ports. */ configASSERT( ( pxSendCompletedCallback == NULL ) && ( pxReceiveCompletedCallback == NULL ) ); if( ( pxSendCompletedCallback == NULL ) && ( pxReceiveCompletedCallback == NULL ) ) { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, NULL, NULL ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, NULL, NULL ); } } else { traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ); xReturn = NULL; } return xReturn; } #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ /*-----------------------------------------------------------*/ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) /* FREERTOS_SYSTEM_CALL */ { StreamBufferHandle_t xReturn; /** * Streambuffer application level callback functionality is disabled for MPU * enabled ports. */ configASSERT( ( pxSendCompletedCallback == NULL ) && ( pxReceiveCompletedCallback == NULL ) ); if( ( pxSendCompletedCallback == NULL ) && ( pxReceiveCompletedCallback == NULL ) ) { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); xReturn = xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pucStreamBufferStorageArea, pxStaticStreamBuffer, NULL, NULL ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { xReturn = xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pucStreamBufferStorageArea, pxStaticStreamBuffer, NULL, NULL ); } } else { traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ); xReturn = NULL; } return xReturn; } #endif /* configSUPPORT_STATIC_ALLOCATION */ /*-----------------------------------------------------------*/ /* Functions that the application writer wants to execute in privileged mode * can be defined in application_defined_privileged_functions.h. The functions * must take the same format as those above whereby the privilege state on exit * equals the privilege state on entry. For example: * * void MPU_FunctionName( [parameters ] ) FREERTOS_SYSTEM_CALL; * void MPU_FunctionName( [parameters ] ) * { * if( portIS_PRIVILEGED() == pdFALSE ) * { * portRAISE_PRIVILEGE(); * portMEMORY_BARRIER(); * * FunctionName( [parameters ] ); * portMEMORY_BARRIER(); * * portRESET_PRIVILEGE(); * portMEMORY_BARRIER(); * } * else * { * FunctionName( [parameters ] ); * } * } */ #if configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS == 1 #include "application_defined_privileged_functions.h" #endif /*-----------------------------------------------------------*/ #endif /* portUSING_MPU_WRAPPERS == 1 */ /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CA53_64_BIT/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #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 #endif #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 #endif #ifndef configUNIQUE_INTERRUPT_PRIORITIES #error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif #ifndef configSETUP_TICK_INTERRUPT #error configSETUP_TICK_INTERRUPT() must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif /* configSETUP_TICK_INTERRUPT */ #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 #endif #if configMAX_API_CALL_INTERRUPT_PRIORITY == 0 #error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0 #endif #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 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #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. #endif #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /* In case security extensions are implemented. */ #if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) #error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) #endif /* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in portmacro.h. */ #ifndef configCLEAR_TICK_INTERRUPT #define configCLEAR_TICK_INTERRUPT() #endif /* A critical section is exited when the critical section nesting count reaches this value. */ #define portNO_CRITICAL_NESTING ( ( size_t ) 0 ) /* In all GICs 255 can be written to the priority mask register to unmask all (but the lowest) interrupt priority. */ #define portUNMASK_VALUE ( 0xFFUL ) /* 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 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 context. */ #define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 ) /* Constants required to setup the initial task context. */ #define portSP_ELx ( ( StackType_t ) 0x01 ) #define portSP_EL0 ( ( StackType_t ) 0x00 ) #if defined( GUEST ) #define portEL1 ( ( StackType_t ) 0x04 ) #define portINITIAL_PSTATE ( portEL1 | portSP_EL0 ) #else #define portEL3 ( ( StackType_t ) 0x0c ) /* At the time of writing, the BSP only supports EL3. */ #define portINITIAL_PSTATE ( portEL3 | portSP_EL0 ) #endif /* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary point is zero. */ #define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 ) /* Masks all bits in the APSR other than the mode bits. */ #define portAPSR_MODE_BITS_MASK ( 0x0C ) /* The I bit in the DAIF bits. */ #define portDAIF_I ( 0x80 ) /* Macro to unmask all interrupt priorities. */ #define portCLEAR_INTERRUPT_MASK() \ { \ portDISABLE_INTERRUPTS(); \ portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \ __asm volatile ( "DSB SY \n" \ "ISB SY \n" ); \ portENABLE_INTERRUPTS(); \ } /* Hardware specifics used when sanity checking the configuration. */ #define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portBIT_0_SET ( ( uint8_t ) 0x01 ) /*-----------------------------------------------------------*/ /* * Starts the first task executing. This function is necessarily written in * assembly code so is implemented in portASM.s. */ extern void vPortRestoreTaskContext( void ); /*-----------------------------------------------------------*/ /* 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 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 automatically be set to 0 when the first task is started. */ volatile uint64_t ullCriticalNesting = 9999ULL; /* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero then floating point context must be saved and restored for the task. */ uint64_t ullPortTaskHasFPUContext = pdFALSE; /* Set to 1 to pend a context switch from an ISR. */ uint64_t ullPortYieldRequired = pdFALSE; /* Counts the interrupt nesting depth. A context switch is only performed if if the nesting depth is 0. */ uint64_t ullPortInterruptNesting = 0; /* Used in the ASM code. */ __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 ullICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS; __attribute__(( used )) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { /* Setup the initial stack of the task. The stack is set exactly as expected by the portRESTORE_CONTEXT() macro. */ /* First all the general purpose registers. */ pxTopOfStack--; *pxTopOfStack = 0x0101010101010101ULL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = 0x0303030303030303ULL; /* R3 */ pxTopOfStack--; *pxTopOfStack = 0x0202020202020202ULL; /* R2 */ pxTopOfStack--; *pxTopOfStack = 0x0505050505050505ULL; /* R5 */ pxTopOfStack--; *pxTopOfStack = 0x0404040404040404ULL; /* R4 */ pxTopOfStack--; *pxTopOfStack = 0x0707070707070707ULL; /* R7 */ pxTopOfStack--; *pxTopOfStack = 0x0606060606060606ULL; /* R6 */ pxTopOfStack--; *pxTopOfStack = 0x0909090909090909ULL; /* R9 */ pxTopOfStack--; *pxTopOfStack = 0x0808080808080808ULL; /* R8 */ pxTopOfStack--; *pxTopOfStack = 0x1111111111111111ULL; /* R11 */ pxTopOfStack--; *pxTopOfStack = 0x1010101010101010ULL; /* R10 */ pxTopOfStack--; *pxTopOfStack = 0x1313131313131313ULL; /* R13 */ pxTopOfStack--; *pxTopOfStack = 0x1212121212121212ULL; /* R12 */ pxTopOfStack--; *pxTopOfStack = 0x1515151515151515ULL; /* R15 */ pxTopOfStack--; *pxTopOfStack = 0x1414141414141414ULL; /* R14 */ pxTopOfStack--; *pxTopOfStack = 0x1717171717171717ULL; /* R17 */ pxTopOfStack--; *pxTopOfStack = 0x1616161616161616ULL; /* R16 */ pxTopOfStack--; *pxTopOfStack = 0x1919191919191919ULL; /* R19 */ pxTopOfStack--; *pxTopOfStack = 0x1818181818181818ULL; /* R18 */ pxTopOfStack--; *pxTopOfStack = 0x2121212121212121ULL; /* R21 */ pxTopOfStack--; *pxTopOfStack = 0x2020202020202020ULL; /* R20 */ pxTopOfStack--; *pxTopOfStack = 0x2323232323232323ULL; /* R23 */ pxTopOfStack--; *pxTopOfStack = 0x2222222222222222ULL; /* R22 */ pxTopOfStack--; *pxTopOfStack = 0x2525252525252525ULL; /* R25 */ pxTopOfStack--; *pxTopOfStack = 0x2424242424242424ULL; /* R24 */ pxTopOfStack--; *pxTopOfStack = 0x2727272727272727ULL; /* R27 */ pxTopOfStack--; *pxTopOfStack = 0x2626262626262626ULL; /* R26 */ pxTopOfStack--; *pxTopOfStack = 0x2929292929292929ULL; /* R29 */ pxTopOfStack--; *pxTopOfStack = 0x2828282828282828ULL; /* R28 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_PSTATE; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */ pxTopOfStack--; /* The task will start with a critical nesting count of 0 as interrupts are enabled. */ *pxTopOfStack = portNO_CRITICAL_NESTING; pxTopOfStack--; /* The task will start without a floating point context. A task that uses the floating point hardware must call vPortTaskUsesFPU() before executing any floating point instructions. */ *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) { uint32_t ulAPSR; #if( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET ); volatile uint8_t ucMaxPriorityValue; /* Determine how many priority bits are implemented in the GIC. Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* Shift to the least significant bits. */ while( ( ucMaxPriorityValue & portBIT_0_SET ) != portBIT_0_SET ) { ucMaxPriorityValue >>= ( uint8_t ) 0x01; } /* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read value. */ configASSERT( ucMaxPriorityValue >= portLOWEST_INTERRUPT_PRIORITY ); /* Restore the clobbered interrupt priority register to its original value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* At the time of writing, the BSP only supports EL3. */ __asm volatile ( "MRS %0, CurrentEL" : "=r" ( ulAPSR ) ); ulAPSR &= portAPSR_MODE_BITS_MASK; #if defined( GUEST ) #warning Building for execution as a guest under XEN. THIS IS NOT A FULLY TESTED PATH. configASSERT( ulAPSR == portEL1 ); if( ulAPSR == portEL1 ) #else configASSERT( ulAPSR == portEL3 ); if( ulAPSR == portEL3 ) #endif { /* Only continue if the binary point value is set to its lowest possible setting. See the comments in vPortValidateInterruptPriority() below for more information. */ configASSERT( ( 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 not execute while the scheduler is being started. Interrupts are automatically turned back on in the CPU when the first task starts executing. */ portDISABLE_INTERRUPTS(); /* Start the timer that generates the tick ISR. */ configSETUP_TICK_INTERRUPT(); /* Start the first task executing. */ vPortRestoreTaskContext(); } } return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. Artificially force an assert. */ configASSERT( ullCriticalNesting == 1000ULL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { /* Mask interrupts up to the max syscall interrupt priority. */ uxPortSetInterruptMask(); /* Now interrupts are disabled ullCriticalNesting can be accessed directly. Increment ullCriticalNesting to keep a count of how many times portENTER_CRITICAL() has been called. */ ullCriticalNesting++; /* 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 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 assert function also uses a critical section. */ if( ullCriticalNesting == 1ULL ) { configASSERT( ullPortInterruptNesting == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { if( ullCriticalNesting > portNO_CRITICAL_NESTING ) { /* Decrement the nesting count as the critical section is being exited. */ ullCriticalNesting--; /* If the nesting level has reached zero then all interrupt priorities must be re-enabled. */ if( ullCriticalNesting == portNO_CRITICAL_NESTING ) { /* Critical nesting has reached zero so all interrupt priorities should be unmasked. */ portCLEAR_INTERRUPT_MASK(); } } } /*-----------------------------------------------------------*/ void FreeRTOS_Tick_Handler( void ) { /* Must be the lowest possible priority. */ #if !defined( QEMU ) { configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER == ( uint32_t ) ( portLOWEST_USABLE_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); } #endif /* Interrupts should not be enabled before this point. */ #if( configASSERT_DEFINED == 1 ) { uint32_t ulMaskBits; __asm volatile( "mrs %0, daif" : "=r"( ulMaskBits ) :: "memory" ); configASSERT( ( ulMaskBits & portDAIF_I ) != 0 ); } #endif /* configASSERT_DEFINED */ /* Set interrupt mask before altering scheduler structures. The tick 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 necessary to turn off interrupts in the CPU itself while the ICCPMR is being updated. */ portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); __asm volatile ( "dsb sy \n" "isb sy \n" ::: "memory" ); /* Ok to enable interrupts after the interrupt source has been cleared. */ configCLEAR_TICK_INTERRUPT(); portENABLE_INTERRUPTS(); /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { ullPortYieldRequired = pdTRUE; } /* Ensure all interrupt priorities are active again. */ portCLEAR_INTERRUPT_MASK(); } /*-----------------------------------------------------------*/ void vPortTaskUsesFPU( void ) { /* 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). */ ullPortTaskHasFPUContext = pdTRUE; /* Consider initialising the FPSR here - but probably not necessary in AArch64. */ } /*-----------------------------------------------------------*/ void vPortClearInterruptMask( UBaseType_t uxNewMaskValue ) { if( uxNewMaskValue == pdFALSE ) { portCLEAR_INTERRUPT_MASK(); } } /*-----------------------------------------------------------*/ UBaseType_t uxPortSetInterruptMask( void ) { uint32_t ulReturn; /* Interrupt in the CPU must be turned off while the ICCPMR is being updated. */ portDISABLE_INTERRUPTS(); if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ) { /* Interrupts were already masked. */ ulReturn = pdTRUE; } else { ulReturn = pdFALSE; portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); __asm volatile ( "dsb sy \n" "isb sy \n" ::: "memory" ); } portENABLE_INTERRUPTS(); return ulReturn; } /*-----------------------------------------------------------*/ #if( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { /* The following assertion will fail if a service routine (ISR) for an interrupt that has been assigned a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API function. ISR safe FreeRTOS API functions must *only* be called from interrupts that have been assigned a priority at or below configMAX_SYSCALL_INTERRUPT_PRIORITY. Numerically low interrupt priority numbers represent logically high interrupt priorities, therefore the priority of the interrupt must be set to a value equal to or numerically *higher* than configMAX_SYSCALL_INTERRUPT_PRIORITY. FreeRTOS maintains separate thread and ISR API functions to ensure interrupt entry is as fast and simple as possible. */ configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); /* Priority grouping: The interrupt controller (GIC) allows the bits that define each interrupt's priority to be split between bits that define the interrupt's pre-emption priority bits and bits that define the interrupt's sub-priority. For simplicity all bits must be defined to be pre-emption priority bits. The following assertion will fail if this is not the case (if some bits represent a sub-priority). 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 possible value (which may be above 0). */ configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); } #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CA53_64_BIT/portASM.S ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ .text /* Variables and functions. */ .extern ullMaxAPIPriorityMask .extern pxCurrentTCB .extern vTaskSwitchContext .extern vApplicationIRQHandler .extern ullPortInterruptNesting .extern ullPortTaskHasFPUContext .extern ullCriticalNesting .extern ullPortYieldRequired .extern ullICCEOIR .extern ullICCIAR .extern _freertos_vector_table .global FreeRTOS_IRQ_Handler .global FreeRTOS_SWI_Handler .global vPortRestoreTaskContext .macro portSAVE_CONTEXT /* Switch to use the EL0 stack pointer. */ MSR SPSEL, #0 /* Save the entire context. */ STP X0, X1, [SP, #-0x10]! STP X2, X3, [SP, #-0x10]! STP X4, X5, [SP, #-0x10]! STP X6, X7, [SP, #-0x10]! STP X8, X9, [SP, #-0x10]! STP X10, X11, [SP, #-0x10]! STP X12, X13, [SP, #-0x10]! STP X14, X15, [SP, #-0x10]! STP X16, X17, [SP, #-0x10]! STP X18, X19, [SP, #-0x10]! STP X20, X21, [SP, #-0x10]! STP X22, X23, [SP, #-0x10]! STP X24, X25, [SP, #-0x10]! STP X26, X27, [SP, #-0x10]! STP X28, X29, [SP, #-0x10]! STP X30, XZR, [SP, #-0x10]! /* Save the SPSR. */ #if defined( GUEST ) MRS X3, SPSR_EL1 MRS X2, ELR_EL1 #else MRS X3, SPSR_EL3 /* Save the ELR. */ MRS X2, ELR_EL3 #endif STP X2, X3, [SP, #-0x10]! /* Save the critical section nesting depth. */ LDR X0, ullCriticalNestingConst LDR X3, [X0] /* Save the FPU context indicator. */ LDR X0, ullPortTaskHasFPUContextConst LDR X2, [X0] /* Save the FPU context, if any (32 128-bit registers). */ CMP X2, #0 B.EQ 1f STP Q0, Q1, [SP,#-0x20]! STP Q2, Q3, [SP,#-0x20]! STP Q4, Q5, [SP,#-0x20]! STP Q6, Q7, [SP,#-0x20]! STP Q8, Q9, [SP,#-0x20]! STP Q10, Q11, [SP,#-0x20]! STP Q12, Q13, [SP,#-0x20]! STP Q14, Q15, [SP,#-0x20]! STP Q16, Q17, [SP,#-0x20]! STP Q18, Q19, [SP,#-0x20]! STP Q20, Q21, [SP,#-0x20]! STP Q22, Q23, [SP,#-0x20]! STP Q24, Q25, [SP,#-0x20]! STP Q26, Q27, [SP,#-0x20]! STP Q28, Q29, [SP,#-0x20]! STP Q30, Q31, [SP,#-0x20]! 1: /* Store the critical nesting count and FPU context indicator. */ STP X2, X3, [SP, #-0x10]! LDR X0, pxCurrentTCBConst LDR X1, [X0] MOV X0, SP /* Move SP into X0 for saving. */ STR X0, [X1] /* Switch to use the ELx stack pointer. */ MSR SPSEL, #1 .endm ; /**********************************************************************/ .macro portRESTORE_CONTEXT /* Switch to use the EL0 stack pointer. */ MSR SPSEL, #0 /* Set the SP to point to the stack of the task being restored. */ LDR X0, pxCurrentTCBConst LDR X1, [X0] LDR X0, [X1] MOV SP, X0 LDP X2, X3, [SP], #0x10 /* Critical nesting and FPU context. */ /* Set the PMR register to be correct for the current critical nesting depth. */ LDR X0, ullCriticalNestingConst /* X0 holds the address of ullCriticalNesting. */ MOV X1, #255 /* X1 holds the unmask value. */ LDR X4, ullICCPMRConst /* X4 holds the address of the ICCPMR constant. */ CMP X3, #0 LDR X5, [X4] /* X5 holds the address of the ICCPMR register. */ B.EQ 1f LDR X6, ullMaxAPIPriorityMaskConst LDR X1, [X6] /* X1 holds the mask value. */ 1: STR W1, [X5] /* Write the mask value to ICCPMR. */ DSB SY /* _RB_Barriers probably not required here. */ ISB SY STR X3, [X0] /* Restore the task's critical nesting count. */ /* Restore the FPU context indicator. */ LDR X0, ullPortTaskHasFPUContextConst STR X2, [X0] /* Restore the FPU context, if any. */ CMP X2, #0 B.EQ 1f LDP Q30, Q31, [SP], #0x20 LDP Q28, Q29, [SP], #0x20 LDP Q26, Q27, [SP], #0x20 LDP Q24, Q25, [SP], #0x20 LDP Q22, Q23, [SP], #0x20 LDP Q20, Q21, [SP], #0x20 LDP Q18, Q19, [SP], #0x20 LDP Q16, Q17, [SP], #0x20 LDP Q14, Q15, [SP], #0x20 LDP Q12, Q13, [SP], #0x20 LDP Q10, Q11, [SP], #0x20 LDP Q8, Q9, [SP], #0x20 LDP Q6, Q7, [SP], #0x20 LDP Q4, Q5, [SP], #0x20 LDP Q2, Q3, [SP], #0x20 LDP Q0, Q1, [SP], #0x20 1: LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */ #if defined( GUEST ) /* Restore the SPSR. */ MSR SPSR_EL1, X3 /* Restore the ELR. */ MSR ELR_EL1, X2 #else /* Restore the SPSR. */ MSR SPSR_EL3, X3 /*_RB_ Assumes started in EL3. */ /* Restore the ELR. */ MSR ELR_EL3, X2 #endif LDP X30, XZR, [SP], #0x10 LDP X28, X29, [SP], #0x10 LDP X26, X27, [SP], #0x10 LDP X24, X25, [SP], #0x10 LDP X22, X23, [SP], #0x10 LDP X20, X21, [SP], #0x10 LDP X18, X19, [SP], #0x10 LDP X16, X17, [SP], #0x10 LDP X14, X15, [SP], #0x10 LDP X12, X13, [SP], #0x10 LDP X10, X11, [SP], #0x10 LDP X8, X9, [SP], #0x10 LDP X6, X7, [SP], #0x10 LDP X4, X5, [SP], #0x10 LDP X2, X3, [SP], #0x10 LDP X0, X1, [SP], #0x10 /* Switch to use the ELx stack pointer. _RB_ Might not be required. */ MSR SPSEL, #1 ERET .endm /****************************************************************************** * FreeRTOS_SWI_Handler handler is used to perform a context switch. *****************************************************************************/ .align 8 .type FreeRTOS_SWI_Handler, %function FreeRTOS_SWI_Handler: /* Save the context of the current task and select a new task to run. */ portSAVE_CONTEXT #if defined( GUEST ) MRS X0, ESR_EL1 #else MRS X0, ESR_EL3 #endif LSR X1, X0, #26 #if defined( GUEST ) CMP X1, #0x15 /* 0x15 = SVC instruction. */ #else CMP X1, #0x17 /* 0x17 = SMC instruction. */ #endif B.NE FreeRTOS_Abort BL vTaskSwitchContext portRESTORE_CONTEXT FreeRTOS_Abort: /* Full ESR is in X0, exception class code is in X1. */ B . /****************************************************************************** * vPortRestoreTaskContext is used to start the scheduler. *****************************************************************************/ .align 8 .type vPortRestoreTaskContext, %function vPortRestoreTaskContext: .set freertos_vector_base, _freertos_vector_table /* Install the FreeRTOS interrupt handlers. */ LDR X1, =freertos_vector_base #if defined( GUEST ) MSR VBAR_EL1, X1 #else MSR VBAR_EL3, X1 #endif DSB SY ISB SY /* Start the first task. */ portRESTORE_CONTEXT /****************************************************************************** * FreeRTOS_IRQ_Handler handles IRQ entry and exit. *****************************************************************************/ .align 8 .type FreeRTOS_IRQ_Handler, %function FreeRTOS_IRQ_Handler: /* Save volatile registers. */ STP X0, X1, [SP, #-0x10]! STP X2, X3, [SP, #-0x10]! STP X4, X5, [SP, #-0x10]! STP X6, X7, [SP, #-0x10]! STP X8, X9, [SP, #-0x10]! STP X10, X11, [SP, #-0x10]! STP X12, X13, [SP, #-0x10]! STP X14, X15, [SP, #-0x10]! STP X16, X17, [SP, #-0x10]! STP X18, X19, [SP, #-0x10]! STP X29, X30, [SP, #-0x10]! /* Save the SPSR and ELR. */ #if defined( GUEST ) MRS X3, SPSR_EL1 MRS X2, ELR_EL1 #else MRS X3, SPSR_EL3 MRS X2, ELR_EL3 #endif STP X2, X3, [SP, #-0x10]! /* Increment the interrupt nesting counter. */ LDR X5, ullPortInterruptNestingConst LDR X1, [X5] /* Old nesting count in X1. */ ADD X6, X1, #1 STR X6, [X5] /* Address of nesting count variable in X5. */ /* Maintain the interrupt nesting information across the function call. */ STP X1, X5, [SP, #-0x10]! /* Read value from the interrupt acknowledge register, which is stored in W0 for future parameter and interrupt clearing use. */ LDR X2, ullICCIARConst LDR X3, [X2] LDR W0, [X3] /* ICCIAR in W0 as parameter. */ /* Maintain the ICCIAR value across the function call. */ STP X0, X1, [SP, #-0x10]! /* Call the C handler. */ BL vApplicationIRQHandler /* Disable interrupts. */ MSR DAIFSET, #2 DSB SY ISB SY /* Restore the ICCIAR value. */ LDP X0, X1, [SP], #0x10 /* End IRQ processing by writing ICCIAR to the EOI register. */ LDR X4, ullICCEOIRConst LDR X4, [X4] STR W0, [X4] /* Restore the critical nesting count. */ LDP X1, X5, [SP], #0x10 STR X1, [X5] /* Has interrupt nesting unwound? */ CMP X1, #0 B.NE Exit_IRQ_No_Context_Switch /* Is a context switch required? */ LDR X0, ullPortYieldRequiredConst LDR X1, [X0] CMP X1, #0 B.EQ Exit_IRQ_No_Context_Switch /* Reset ullPortYieldRequired to 0. */ MOV X2, #0 STR X2, [X0] /* Restore volatile registers. */ LDP X4, X5, [SP], #0x10 /* SPSR and ELR. */ #if defined( GUEST ) MSR SPSR_EL1, X5 MSR ELR_EL1, X4 #else MSR SPSR_EL3, X5 /*_RB_ Assumes started in EL3. */ MSR ELR_EL3, X4 #endif DSB SY ISB SY LDP X29, X30, [SP], #0x10 LDP X18, X19, [SP], #0x10 LDP X16, X17, [SP], #0x10 LDP X14, X15, [SP], #0x10 LDP X12, X13, [SP], #0x10 LDP X10, X11, [SP], #0x10 LDP X8, X9, [SP], #0x10 LDP X6, X7, [SP], #0x10 LDP X4, X5, [SP], #0x10 LDP X2, X3, [SP], #0x10 LDP X0, X1, [SP], #0x10 /* Save the context of the current task and select a new task to run. */ portSAVE_CONTEXT BL vTaskSwitchContext portRESTORE_CONTEXT Exit_IRQ_No_Context_Switch: /* Restore volatile registers. */ LDP X4, X5, [SP], #0x10 /* SPSR and ELR. */ #if defined( GUEST ) MSR SPSR_EL1, X5 MSR ELR_EL1, X4 #else MSR SPSR_EL3, X5 /*_RB_ Assumes started in EL3. */ MSR ELR_EL3, X4 #endif DSB SY ISB SY LDP X29, X30, [SP], #0x10 LDP X18, X19, [SP], #0x10 LDP X16, X17, [SP], #0x10 LDP X14, X15, [SP], #0x10 LDP X12, X13, [SP], #0x10 LDP X10, X11, [SP], #0x10 LDP X8, X9, [SP], #0x10 LDP X6, X7, [SP], #0x10 LDP X4, X5, [SP], #0x10 LDP X2, X3, [SP], #0x10 LDP X0, X1, [SP], #0x10 ERET .align 8 pxCurrentTCBConst: .dword pxCurrentTCB ullCriticalNestingConst: .dword ullCriticalNesting ullPortTaskHasFPUContextConst: .dword ullPortTaskHasFPUContext ullICCPMRConst: .dword ullICCPMR ullMaxAPIPriorityMaskConst: .dword ullMaxAPIPriorityMask ullPortInterruptNestingConst: .dword ullPortInterruptNesting ullPortYieldRequiredConst: .dword ullPortYieldRequired ullICCIARConst: .dword ullICCIAR ullICCEOIRConst: .dword ullICCEOIR vApplicationIRQHandlerConst: .word vApplicationIRQHandler .end ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CA53_64_BIT/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE size_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef portBASE_TYPE BaseType_t; typedef uint64_t UBaseType_t; typedef uint64_t TickType_t; #define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff ) /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 /*-----------------------------------------------------------*/ /* Hardware specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 16 #define portPOINTER_SIZE_TYPE uint64_t /*-----------------------------------------------------------*/ /* Task utilities. */ /* Called at the end of an ISR that can cause a context switch. */ #define portEND_SWITCHING_ISR( xSwitchRequired )\ { \ extern uint64_t ullPortYieldRequired; \ \ if( xSwitchRequired != pdFALSE ) \ { \ ullPortYieldRequired = pdTRUE; \ } \ } #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #if defined( GUEST ) #define portYIELD() __asm volatile ( "SVC 0" ::: "memory" ) #else #define portYIELD() __asm volatile ( "SMC 0" ::: "memory" ) #endif /*----------------------------------------------------------- * Critical section control *----------------------------------------------------------*/ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); extern UBaseType_t uxPortSetInterruptMask( void ); extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue ); extern void vPortInstallFreeRTOSVectorTable( void ); #define portDISABLE_INTERRUPTS() \ __asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \ __asm volatile ( "DSB SY" ); \ __asm volatile ( "ISB SY" ); #define portENABLE_INTERRUPTS() \ __asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \ __asm volatile ( "DSB SY" ); \ __asm volatile ( "ISB SY" ); /* These macros do not globally disable/enable interrupts. They do mask off interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */ #define portENTER_CRITICAL() vPortEnterCritical(); #define portEXIT_CRITICAL() vPortExitCritical(); #define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x) /*-----------------------------------------------------------*/ /* 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 macros is used. */ #define portTASK_FUNCTION_PROTO( 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 handler for whichever peripheral is used to generate the RTOS tick. */ void FreeRTOS_Tick_Handler( void ); /* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() before any floating point instructions are executed. */ void vPortTaskUsesFPU( void ); #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() #define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) #define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL ) /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* configASSERT */ #define portNOP() __asm volatile( "NOP" ) #define portINLINE __inline #ifdef __cplusplus } /* extern C */ #endif /* The number of bits to shift for an interrupt priority is dependent on the number of bits implemented by the interrupt controller. */ #if configUNIQUE_INTERRUPT_PRIORITIES == 16 #define portPRIORITY_SHIFT 4 #define portMAX_BINARY_POINT_VALUE 3 #elif configUNIQUE_INTERRUPT_PRIORITIES == 32 #define portPRIORITY_SHIFT 3 #define portMAX_BINARY_POINT_VALUE 2 #elif configUNIQUE_INTERRUPT_PRIORITIES == 64 #define portPRIORITY_SHIFT 2 #define portMAX_BINARY_POINT_VALUE 1 #elif configUNIQUE_INTERRUPT_PRIORITIES == 128 #define portPRIORITY_SHIFT 1 #define portMAX_BINARY_POINT_VALUE 0 #elif configUNIQUE_INTERRUPT_PRIORITIES == 256 #define portPRIORITY_SHIFT 0 #define portMAX_BINARY_POINT_VALUE 0 #else #error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware #endif /* Interrupt controller access addresses. */ #define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 ) #define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C ) #define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 ) #define portICCBPR_BINARY_POINT_OFFSET ( 0x08 ) #define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 ) #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 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 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 portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) ) #define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CA53_64_BIT_SRE/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #ifndef configUNIQUE_INTERRUPT_PRIORITIES #error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif #ifndef configSETUP_TICK_INTERRUPT #error configSETUP_TICK_INTERRUPT() must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif /* configSETUP_TICK_INTERRUPT */ #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 #endif #if configMAX_API_CALL_INTERRUPT_PRIORITY == 0 #error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0 #endif #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 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #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. #endif #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /* In case security extensions are implemented. */ #if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) #error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) #endif /* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in portmacro.h. */ #ifndef configCLEAR_TICK_INTERRUPT #define configCLEAR_TICK_INTERRUPT() #endif /* A critical section is exited when the critical section nesting count reaches this value. */ #define portNO_CRITICAL_NESTING ( ( size_t ) 0 ) /* In all GICs 255 can be written to the priority mask register to unmask all (but the lowest) interrupt priority. */ #define portUNMASK_VALUE ( 0xFFUL ) /* 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 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 context. */ #define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 ) /* Constants required to setup the initial task context. */ #define portSP_ELx ( ( StackType_t ) 0x01 ) #define portSP_EL0 ( ( StackType_t ) 0x00 ) #if defined( GUEST ) #define portEL1 ( ( StackType_t ) 0x04 ) #define portINITIAL_PSTATE ( portEL1 | portSP_EL0 ) #else #define portEL3 ( ( StackType_t ) 0x0c ) /* At the time of writing, the BSP only supports EL3. */ #define portINITIAL_PSTATE ( portEL3 | portSP_EL0 ) #endif /* Masks all bits in the APSR other than the mode bits. */ #define portAPSR_MODE_BITS_MASK ( 0x0C ) /* The I bit in the DAIF bits. */ #define portDAIF_I ( 0x80 ) /* Macro to unmask all interrupt priorities. */ /* s3_0_c4_c6_0 is ICC_PMR_EL1. */ #define portCLEAR_INTERRUPT_MASK() \ { \ __asm volatile ( "MSR DAIFSET, #2 \n" \ "DSB SY \n" \ "ISB SY \n" \ "MSR s3_0_c4_c6_0, %0 \n" \ "DSB SY \n" \ "ISB SY \n" \ "MSR DAIFCLR, #2 \n" \ "DSB SY \n" \ "ISB SY \n" \ ::"r"( portUNMASK_VALUE ) ); \ } /*-----------------------------------------------------------*/ /* * Starts the first task executing. This function is necessarily written in * assembly code so is implemented in portASM.s. */ extern void vPortRestoreTaskContext( void ); /*-----------------------------------------------------------*/ /* 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 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 automatically be set to 0 when the first task is started. */ volatile uint64_t ullCriticalNesting = 9999ULL; /* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero then floating point context must be saved and restored for the task. */ uint64_t ullPortTaskHasFPUContext = pdFALSE; /* Set to 1 to pend a context switch from an ISR. */ uint64_t ullPortYieldRequired = pdFALSE; /* Counts the interrupt nesting depth. A context switch is only performed if if the nesting depth is 0. */ uint64_t ullPortInterruptNesting = 0; /* Used in the ASM code. */ __attribute__(( used )) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { /* Setup the initial stack of the task. The stack is set exactly as expected by the portRESTORE_CONTEXT() macro. */ /* First all the general purpose registers. */ pxTopOfStack--; *pxTopOfStack = 0x0101010101010101ULL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = 0x0303030303030303ULL; /* R3 */ pxTopOfStack--; *pxTopOfStack = 0x0202020202020202ULL; /* R2 */ pxTopOfStack--; *pxTopOfStack = 0x0505050505050505ULL; /* R5 */ pxTopOfStack--; *pxTopOfStack = 0x0404040404040404ULL; /* R4 */ pxTopOfStack--; *pxTopOfStack = 0x0707070707070707ULL; /* R7 */ pxTopOfStack--; *pxTopOfStack = 0x0606060606060606ULL; /* R6 */ pxTopOfStack--; *pxTopOfStack = 0x0909090909090909ULL; /* R9 */ pxTopOfStack--; *pxTopOfStack = 0x0808080808080808ULL; /* R8 */ pxTopOfStack--; *pxTopOfStack = 0x1111111111111111ULL; /* R11 */ pxTopOfStack--; *pxTopOfStack = 0x1010101010101010ULL; /* R10 */ pxTopOfStack--; *pxTopOfStack = 0x1313131313131313ULL; /* R13 */ pxTopOfStack--; *pxTopOfStack = 0x1212121212121212ULL; /* R12 */ pxTopOfStack--; *pxTopOfStack = 0x1515151515151515ULL; /* R15 */ pxTopOfStack--; *pxTopOfStack = 0x1414141414141414ULL; /* R14 */ pxTopOfStack--; *pxTopOfStack = 0x1717171717171717ULL; /* R17 */ pxTopOfStack--; *pxTopOfStack = 0x1616161616161616ULL; /* R16 */ pxTopOfStack--; *pxTopOfStack = 0x1919191919191919ULL; /* R19 */ pxTopOfStack--; *pxTopOfStack = 0x1818181818181818ULL; /* R18 */ pxTopOfStack--; *pxTopOfStack = 0x2121212121212121ULL; /* R21 */ pxTopOfStack--; *pxTopOfStack = 0x2020202020202020ULL; /* R20 */ pxTopOfStack--; *pxTopOfStack = 0x2323232323232323ULL; /* R23 */ pxTopOfStack--; *pxTopOfStack = 0x2222222222222222ULL; /* R22 */ pxTopOfStack--; *pxTopOfStack = 0x2525252525252525ULL; /* R25 */ pxTopOfStack--; *pxTopOfStack = 0x2424242424242424ULL; /* R24 */ pxTopOfStack--; *pxTopOfStack = 0x2727272727272727ULL; /* R27 */ pxTopOfStack--; *pxTopOfStack = 0x2626262626262626ULL; /* R26 */ pxTopOfStack--; *pxTopOfStack = 0x2929292929292929ULL; /* R29 */ pxTopOfStack--; *pxTopOfStack = 0x2828282828282828ULL; /* R28 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_PSTATE; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */ pxTopOfStack--; /* The task will start with a critical nesting count of 0 as interrupts are enabled. */ *pxTopOfStack = portNO_CRITICAL_NESTING; pxTopOfStack--; /* The task will start without a floating point context. A task that uses the floating point hardware must call vPortTaskUsesFPU() before executing any floating point instructions. */ *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) { uint32_t ulAPSR; __asm volatile ( "MRS %0, CurrentEL" : "=r" ( ulAPSR ) ); ulAPSR &= portAPSR_MODE_BITS_MASK; #if defined( GUEST ) configASSERT( ulAPSR == portEL1 ); if( ulAPSR == portEL1 ) #else configASSERT( ulAPSR == portEL3 ); if( ulAPSR == portEL3 ) #endif { /* Interrupts are turned off in the CPU itself to ensure a tick does not execute while the scheduler is being started. Interrupts are automatically turned back on in the CPU when the first task starts executing. */ portDISABLE_INTERRUPTS(); /* Start the timer that generates the tick ISR. */ configSETUP_TICK_INTERRUPT(); /* Start the first task executing. */ vPortRestoreTaskContext(); } return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. Artificially force an assert. */ configASSERT( ullCriticalNesting == 1000ULL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { /* Mask interrupts up to the max syscall interrupt priority. */ uxPortSetInterruptMask(); /* Now interrupts are disabled ullCriticalNesting can be accessed directly. Increment ullCriticalNesting to keep a count of how many times portENTER_CRITICAL() has been called. */ ullCriticalNesting++; /* 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 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 assert function also uses a critical section. */ if( ullCriticalNesting == 1ULL ) { configASSERT( ullPortInterruptNesting == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { if( ullCriticalNesting > portNO_CRITICAL_NESTING ) { /* Decrement the nesting count as the critical section is being exited. */ ullCriticalNesting--; /* If the nesting level has reached zero then all interrupt priorities must be re-enabled. */ if( ullCriticalNesting == portNO_CRITICAL_NESTING ) { /* Critical nesting has reached zero so all interrupt priorities should be unmasked. */ portCLEAR_INTERRUPT_MASK(); } } } /*-----------------------------------------------------------*/ void FreeRTOS_Tick_Handler( void ) { /* Must be the lowest possible priority. */ #if !defined( QEMU ) { uint64_t ullRunningInterruptPriority; /* s3_0_c12_c11_3 is ICC_RPR_EL1. */ __asm volatile ( "MRS %0, s3_0_c12_c11_3" : "=r" ( ullRunningInterruptPriority ) ); configASSERT( ullRunningInterruptPriority == ( portLOWEST_USABLE_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); } #endif /* Interrupts should not be enabled before this point. */ #if( configASSERT_DEFINED == 1 ) { uint32_t ulMaskBits; __asm volatile( "MRS %0, DAIF" : "=r"( ulMaskBits ) :: "memory" ); configASSERT( ( ulMaskBits & portDAIF_I ) != 0 ); } #endif /* configASSERT_DEFINED */ /* Set interrupt mask before altering scheduler structures. The tick 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 necessary to turn off interrupts in the CPU itself while the ICCPMR is being updated. */ /* s3_0_c4_c6_0 is ICC_PMR_EL1. */ __asm volatile ( "MSR s3_0_c4_c6_0, %0 \n" "DSB SY \n" "ISB SY \n" :: "r" ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) : "memory" ); /* Ok to enable interrupts after the interrupt source has been cleared. */ configCLEAR_TICK_INTERRUPT(); portENABLE_INTERRUPTS(); /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { ullPortYieldRequired = pdTRUE; } /* Ensure all interrupt priorities are active again. */ portCLEAR_INTERRUPT_MASK(); } /*-----------------------------------------------------------*/ void vPortTaskUsesFPU( void ) { /* 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). */ ullPortTaskHasFPUContext = pdTRUE; /* Consider initialising the FPSR here - but probably not necessary in AArch64. */ } /*-----------------------------------------------------------*/ void vPortClearInterruptMask( UBaseType_t uxNewMaskValue ) { if( uxNewMaskValue == pdFALSE ) { portCLEAR_INTERRUPT_MASK(); } } /*-----------------------------------------------------------*/ UBaseType_t uxPortSetInterruptMask( void ) { uint32_t ulReturn; uint64_t ullPMRValue; /* Interrupt in the CPU must be turned off while the ICCPMR is being updated. */ portDISABLE_INTERRUPTS(); /* s3_0_c4_c6_0 is ICC_PMR_EL1. */ __asm volatile ( "MRS %0, s3_0_c4_c6_0" : "=r" ( ullPMRValue ) ); if( ullPMRValue == ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ) { /* Interrupts were already masked. */ ulReturn = pdTRUE; } else { ulReturn = pdFALSE; /* s3_0_c4_c6_0 is ICC_PMR_EL1. */ __asm volatile ( "MSR s3_0_c4_c6_0, %0 \n" "DSB SY \n" "ISB SY \n" :: "r" ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) : "memory" ); } portENABLE_INTERRUPTS(); return ulReturn; } /*-----------------------------------------------------------*/ #if( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { /* The following assertion will fail if a service routine (ISR) for an interrupt that has been assigned a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API function. ISR safe FreeRTOS API functions must *only* be called from interrupts that have been assigned a priority at or below configMAX_SYSCALL_INTERRUPT_PRIORITY. Numerically low interrupt priority numbers represent logically high interrupt priorities, therefore the priority of the interrupt must be set to a value equal to or numerically *higher* than configMAX_SYSCALL_INTERRUPT_PRIORITY. FreeRTOS maintains separate thread and ISR API functions to ensure interrupt entry is as fast and simple as possible. */ uint64_t ullRunningInterruptPriority; /* s3_0_c12_c11_3 is ICC_RPR_EL1. */ __asm volatile ( "MRS %0, s3_0_c12_c11_3" : "=r" ( ullRunningInterruptPriority ) ); configASSERT( ullRunningInterruptPriority >= ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); } #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CA53_64_BIT_SRE/portASM.S ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ .text /* Variables and functions. */ .extern ullMaxAPIPriorityMask .extern pxCurrentTCB .extern vTaskSwitchContext .extern vApplicationIRQHandler .extern ullPortInterruptNesting .extern ullPortTaskHasFPUContext .extern ullCriticalNesting .extern ullPortYieldRequired .extern _freertos_vector_table .global FreeRTOS_IRQ_Handler .global FreeRTOS_SWI_Handler .global vPortRestoreTaskContext .macro portSAVE_CONTEXT /* Switch to use the EL0 stack pointer. */ MSR SPSEL, #0 /* Save the entire context. */ STP X0, X1, [SP, #-0x10]! STP X2, X3, [SP, #-0x10]! STP X4, X5, [SP, #-0x10]! STP X6, X7, [SP, #-0x10]! STP X8, X9, [SP, #-0x10]! STP X10, X11, [SP, #-0x10]! STP X12, X13, [SP, #-0x10]! STP X14, X15, [SP, #-0x10]! STP X16, X17, [SP, #-0x10]! STP X18, X19, [SP, #-0x10]! STP X20, X21, [SP, #-0x10]! STP X22, X23, [SP, #-0x10]! STP X24, X25, [SP, #-0x10]! STP X26, X27, [SP, #-0x10]! STP X28, X29, [SP, #-0x10]! STP X30, XZR, [SP, #-0x10]! /* Save the SPSR. */ #if defined( GUEST ) MRS X3, SPSR_EL1 MRS X2, ELR_EL1 #else MRS X3, SPSR_EL3 /* Save the ELR. */ MRS X2, ELR_EL3 #endif STP X2, X3, [SP, #-0x10]! /* Save the critical section nesting depth. */ LDR X0, ullCriticalNestingConst LDR X3, [X0] /* Save the FPU context indicator. */ LDR X0, ullPortTaskHasFPUContextConst LDR X2, [X0] /* Save the FPU context, if any (32 128-bit registers). */ CMP X2, #0 B.EQ 1f STP Q0, Q1, [SP,#-0x20]! STP Q2, Q3, [SP,#-0x20]! STP Q4, Q5, [SP,#-0x20]! STP Q6, Q7, [SP,#-0x20]! STP Q8, Q9, [SP,#-0x20]! STP Q10, Q11, [SP,#-0x20]! STP Q12, Q13, [SP,#-0x20]! STP Q14, Q15, [SP,#-0x20]! STP Q16, Q17, [SP,#-0x20]! STP Q18, Q19, [SP,#-0x20]! STP Q20, Q21, [SP,#-0x20]! STP Q22, Q23, [SP,#-0x20]! STP Q24, Q25, [SP,#-0x20]! STP Q26, Q27, [SP,#-0x20]! STP Q28, Q29, [SP,#-0x20]! STP Q30, Q31, [SP,#-0x20]! 1: /* Store the critical nesting count and FPU context indicator. */ STP X2, X3, [SP, #-0x10]! LDR X0, pxCurrentTCBConst LDR X1, [X0] MOV X0, SP /* Move SP into X0 for saving. */ STR X0, [X1] /* Switch to use the ELx stack pointer. */ MSR SPSEL, #1 .endm ; /**********************************************************************/ .macro portRESTORE_CONTEXT /* Switch to use the EL0 stack pointer. */ MSR SPSEL, #0 /* Set the SP to point to the stack of the task being restored. */ LDR X0, pxCurrentTCBConst LDR X1, [X0] LDR X0, [X1] MOV SP, X0 LDP X2, X3, [SP], #0x10 /* Critical nesting and FPU context. */ /* Set the PMR register to be correct for the current critical nesting depth. */ LDR X0, ullCriticalNestingConst /* X0 holds the address of ullCriticalNesting. */ MOV X1, #255 /* X1 holds the unmask value. */ CMP X3, #0 B.EQ 1f LDR X6, ullMaxAPIPriorityMaskConst LDR X1, [X6] /* X1 holds the mask value. */ 1: MSR s3_0_c4_c6_0, X1 /* Write the mask value to ICCPMR. s3_0_c4_c6_0 is ICC_PMR_EL1. */ DSB SY /* _RB_Barriers probably not required here. */ ISB SY STR X3, [X0] /* Restore the task's critical nesting count. */ /* Restore the FPU context indicator. */ LDR X0, ullPortTaskHasFPUContextConst STR X2, [X0] /* Restore the FPU context, if any. */ CMP X2, #0 B.EQ 1f LDP Q30, Q31, [SP], #0x20 LDP Q28, Q29, [SP], #0x20 LDP Q26, Q27, [SP], #0x20 LDP Q24, Q25, [SP], #0x20 LDP Q22, Q23, [SP], #0x20 LDP Q20, Q21, [SP], #0x20 LDP Q18, Q19, [SP], #0x20 LDP Q16, Q17, [SP], #0x20 LDP Q14, Q15, [SP], #0x20 LDP Q12, Q13, [SP], #0x20 LDP Q10, Q11, [SP], #0x20 LDP Q8, Q9, [SP], #0x20 LDP Q6, Q7, [SP], #0x20 LDP Q4, Q5, [SP], #0x20 LDP Q2, Q3, [SP], #0x20 LDP Q0, Q1, [SP], #0x20 1: LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */ #if defined( GUEST ) /* Restore the SPSR. */ MSR SPSR_EL1, X3 /* Restore the ELR. */ MSR ELR_EL1, X2 #else /* Restore the SPSR. */ MSR SPSR_EL3, X3 /*_RB_ Assumes started in EL3. */ /* Restore the ELR. */ MSR ELR_EL3, X2 #endif LDP X30, XZR, [SP], #0x10 LDP X28, X29, [SP], #0x10 LDP X26, X27, [SP], #0x10 LDP X24, X25, [SP], #0x10 LDP X22, X23, [SP], #0x10 LDP X20, X21, [SP], #0x10 LDP X18, X19, [SP], #0x10 LDP X16, X17, [SP], #0x10 LDP X14, X15, [SP], #0x10 LDP X12, X13, [SP], #0x10 LDP X10, X11, [SP], #0x10 LDP X8, X9, [SP], #0x10 LDP X6, X7, [SP], #0x10 LDP X4, X5, [SP], #0x10 LDP X2, X3, [SP], #0x10 LDP X0, X1, [SP], #0x10 /* Switch to use the ELx stack pointer. _RB_ Might not be required. */ MSR SPSEL, #1 ERET .endm /****************************************************************************** * FreeRTOS_SWI_Handler handler is used to perform a context switch. *****************************************************************************/ .align 8 .type FreeRTOS_SWI_Handler, %function FreeRTOS_SWI_Handler: /* Save the context of the current task and select a new task to run. */ portSAVE_CONTEXT #if defined( GUEST ) MRS X0, ESR_EL1 #else MRS X0, ESR_EL3 #endif LSR X1, X0, #26 #if defined( GUEST ) CMP X1, #0x15 /* 0x15 = SVC instruction. */ #else CMP X1, #0x17 /* 0x17 = SMC instruction. */ #endif B.NE FreeRTOS_Abort BL vTaskSwitchContext portRESTORE_CONTEXT FreeRTOS_Abort: /* Full ESR is in X0, exception class code is in X1. */ B . /****************************************************************************** * vPortRestoreTaskContext is used to start the scheduler. *****************************************************************************/ .align 8 .type vPortRestoreTaskContext, %function vPortRestoreTaskContext: .set freertos_vector_base, _freertos_vector_table /* Install the FreeRTOS interrupt handlers. */ LDR X1, =freertos_vector_base #if defined( GUEST ) MSR VBAR_EL1, X1 #else MSR VBAR_EL3, X1 #endif DSB SY ISB SY /* Start the first task. */ portRESTORE_CONTEXT /****************************************************************************** * FreeRTOS_IRQ_Handler handles IRQ entry and exit. * This handler is supposed to be used only for IRQs and never for FIQs. Per ARM * GIC documentation [1], Group 0 interrupts are always signaled as FIQs. Since * this handler is only for IRQs, We can safely assume Group 1 while accessing * Interrupt Acknowledge and End Of Interrupt registers and therefore, use * ICC_IAR1_EL1 and ICC_EOIR1_EL1. * * [1] https://developer.arm.com/documentation/198123/0300/Arm-CoreLink-GIC-fundamentals *****************************************************************************/ .align 8 .type FreeRTOS_IRQ_Handler, %function FreeRTOS_IRQ_Handler: /* Save volatile registers. */ STP X0, X1, [SP, #-0x10]! STP X2, X3, [SP, #-0x10]! STP X4, X5, [SP, #-0x10]! STP X6, X7, [SP, #-0x10]! STP X8, X9, [SP, #-0x10]! STP X10, X11, [SP, #-0x10]! STP X12, X13, [SP, #-0x10]! STP X14, X15, [SP, #-0x10]! STP X16, X17, [SP, #-0x10]! STP X18, X19, [SP, #-0x10]! STP X29, X30, [SP, #-0x10]! /* Save the SPSR and ELR. */ #if defined( GUEST ) MRS X3, SPSR_EL1 MRS X2, ELR_EL1 #else MRS X3, SPSR_EL3 MRS X2, ELR_EL3 #endif STP X2, X3, [SP, #-0x10]! /* Increment the interrupt nesting counter. */ LDR X5, ullPortInterruptNestingConst LDR X1, [X5] /* Old nesting count in X1. */ ADD X6, X1, #1 STR X6, [X5] /* Address of nesting count variable in X5. */ /* Maintain the interrupt nesting information across the function call. */ STP X1, X5, [SP, #-0x10]! /* Read interrupt ID from the interrupt acknowledge register and store it in X0 for future parameter and interrupt clearing use. */ MRS X0, S3_0_C12_C12_0 /* S3_0_C12_C12_0 is ICC_IAR1_EL1. */ /* Maintain the interrupt ID value across the function call. */ STP X0, X1, [SP, #-0x10]! /* Call the C handler. */ BL vApplicationIRQHandler /* Disable interrupts. */ MSR DAIFSET, #2 DSB SY ISB SY /* Restore the interrupt ID value. */ LDP X0, X1, [SP], #0x10 /* End IRQ processing by writing interrupt ID value to the EOI register. */ MSR S3_0_C12_C12_1, X0 /* S3_0_C12_C12_1 is ICC_EOIR1_EL1. */ /* Restore the critical nesting count. */ LDP X1, X5, [SP], #0x10 STR X1, [X5] /* Has interrupt nesting unwound? */ CMP X1, #0 B.NE Exit_IRQ_No_Context_Switch /* Is a context switch required? */ LDR X0, ullPortYieldRequiredConst LDR X1, [X0] CMP X1, #0 B.EQ Exit_IRQ_No_Context_Switch /* Reset ullPortYieldRequired to 0. */ MOV X2, #0 STR X2, [X0] /* Restore volatile registers. */ LDP X4, X5, [SP], #0x10 /* SPSR and ELR. */ #if defined( GUEST ) MSR SPSR_EL1, X5 MSR ELR_EL1, X4 #else MSR SPSR_EL3, X5 /*_RB_ Assumes started in EL3. */ MSR ELR_EL3, X4 #endif DSB SY ISB SY LDP X29, X30, [SP], #0x10 LDP X18, X19, [SP], #0x10 LDP X16, X17, [SP], #0x10 LDP X14, X15, [SP], #0x10 LDP X12, X13, [SP], #0x10 LDP X10, X11, [SP], #0x10 LDP X8, X9, [SP], #0x10 LDP X6, X7, [SP], #0x10 LDP X4, X5, [SP], #0x10 LDP X2, X3, [SP], #0x10 LDP X0, X1, [SP], #0x10 /* Save the context of the current task and select a new task to run. */ portSAVE_CONTEXT BL vTaskSwitchContext portRESTORE_CONTEXT Exit_IRQ_No_Context_Switch: /* Restore volatile registers. */ LDP X4, X5, [SP], #0x10 /* SPSR and ELR. */ #if defined( GUEST ) MSR SPSR_EL1, X5 MSR ELR_EL1, X4 #else MSR SPSR_EL3, X5 /*_RB_ Assumes started in EL3. */ MSR ELR_EL3, X4 #endif DSB SY ISB SY LDP X29, X30, [SP], #0x10 LDP X18, X19, [SP], #0x10 LDP X16, X17, [SP], #0x10 LDP X14, X15, [SP], #0x10 LDP X12, X13, [SP], #0x10 LDP X10, X11, [SP], #0x10 LDP X8, X9, [SP], #0x10 LDP X6, X7, [SP], #0x10 LDP X4, X5, [SP], #0x10 LDP X2, X3, [SP], #0x10 LDP X0, X1, [SP], #0x10 ERET .align 8 pxCurrentTCBConst: .dword pxCurrentTCB ullCriticalNestingConst: .dword ullCriticalNesting ullPortTaskHasFPUContextConst: .dword ullPortTaskHasFPUContext ullMaxAPIPriorityMaskConst: .dword ullMaxAPIPriorityMask ullPortInterruptNestingConst: .dword ullPortInterruptNesting ullPortYieldRequiredConst: .dword ullPortYieldRequired .end ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CA53_64_BIT_SRE/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE size_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef portBASE_TYPE BaseType_t; typedef uint64_t UBaseType_t; typedef uint64_t TickType_t; #define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff ) /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 /*-----------------------------------------------------------*/ /* Hardware specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 16 #define portPOINTER_SIZE_TYPE uint64_t /*-----------------------------------------------------------*/ /* Task utilities. */ /* Called at the end of an ISR that can cause a context switch. */ #define portEND_SWITCHING_ISR( xSwitchRequired )\ { \ extern uint64_t ullPortYieldRequired; \ \ if( xSwitchRequired != pdFALSE ) \ { \ ullPortYieldRequired = pdTRUE; \ } \ } #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #if defined( GUEST ) #define portYIELD() __asm volatile ( "SVC 0" ::: "memory" ) #else #define portYIELD() __asm volatile ( "SMC 0" ::: "memory" ) #endif /*----------------------------------------------------------- * Critical section control *----------------------------------------------------------*/ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); extern UBaseType_t uxPortSetInterruptMask( void ); extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue ); extern void vPortInstallFreeRTOSVectorTable( void ); #define portDISABLE_INTERRUPTS() \ __asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \ __asm volatile ( "DSB SY" ); \ __asm volatile ( "ISB SY" ); #define portENABLE_INTERRUPTS() \ __asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \ __asm volatile ( "DSB SY" ); \ __asm volatile ( "ISB SY" ); /* These macros do not globally disable/enable interrupts. They do mask off interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */ #define portENTER_CRITICAL() vPortEnterCritical(); #define portEXIT_CRITICAL() vPortExitCritical(); #define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x) /*-----------------------------------------------------------*/ /* 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 macros is used. */ #define portTASK_FUNCTION_PROTO( 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 handler for whichever peripheral is used to generate the RTOS tick. */ void FreeRTOS_Tick_Handler( void ); /* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() before any floating point instructions are executed. */ void vPortTaskUsesFPU( void ); #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() #define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) #define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL ) /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* configASSERT */ #define portNOP() __asm volatile( "NOP" ) #define portINLINE __inline #ifdef __cplusplus } /* extern C */ #endif /* The number of bits to shift for an interrupt priority is dependent on the number of bits implemented by the interrupt controller. */ #if configUNIQUE_INTERRUPT_PRIORITIES == 16 #define portPRIORITY_SHIFT 4 #define portMAX_BINARY_POINT_VALUE 3 #elif configUNIQUE_INTERRUPT_PRIORITIES == 32 #define portPRIORITY_SHIFT 3 #define portMAX_BINARY_POINT_VALUE 2 #elif configUNIQUE_INTERRUPT_PRIORITIES == 64 #define portPRIORITY_SHIFT 2 #define portMAX_BINARY_POINT_VALUE 1 #elif configUNIQUE_INTERRUPT_PRIORITIES == 128 #define portPRIORITY_SHIFT 1 #define portMAX_BINARY_POINT_VALUE 0 #elif configUNIQUE_INTERRUPT_PRIORITIES == 256 #define portPRIORITY_SHIFT 0 #define portMAX_BINARY_POINT_VALUE 0 #else #error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware #endif #define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CA9/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include #include /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #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 #endif #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 #endif #ifndef configUNIQUE_INTERRUPT_PRIORITIES #error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif #ifndef configSETUP_TICK_INTERRUPT #error configSETUP_TICK_INTERRUPT() must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif /* configSETUP_TICK_INTERRUPT */ #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 #endif #if configMAX_API_CALL_INTERRUPT_PRIORITY == 0 #error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0 #endif #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 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #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. #endif #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /* In case security extensions are implemented. */ #if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) #error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) #endif /* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in portmacro.h. */ #ifndef configCLEAR_TICK_INTERRUPT #define configCLEAR_TICK_INTERRUPT() #endif /* A critical section is exited when the critical section nesting count reaches this value. */ #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 ) /* In all GICs 255 can be written to the priority mask register to unmask all (but the lowest) interrupt priority. */ #define portUNMASK_VALUE ( 0xFFUL ) /* 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 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 context. */ #define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 ) /* Constants required to setup the initial task context. */ #define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, IRQ enabled FIQ enabled. */ #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) #define portINTERRUPT_ENABLE_BIT ( 0x80UL ) #define portTHUMB_MODE_ADDRESS ( 0x01UL ) /* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary point is zero. */ #define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 ) /* Masks all bits in the APSR other than the mode bits. */ #define portAPSR_MODE_BITS_MASK ( 0x1F ) /* The value of the mode bits in the APSR when the CPU is executing in user mode. */ #define portAPSR_USER_MODE ( 0x10 ) /* The critical section macros only mask interrupts up to an application determined priority level. Sometimes it is necessary to turn interrupt off in the CPU itself before modifying certain hardware registers. */ #define portCPU_IRQ_DISABLE() \ __asm volatile ( "CPSID i" ::: "memory" ); \ __asm volatile ( "DSB" ); \ __asm volatile ( "ISB" ); #define portCPU_IRQ_ENABLE() \ __asm volatile ( "CPSIE i" ::: "memory" ); \ __asm volatile ( "DSB" ); \ __asm volatile ( "ISB" ); /* Macro to unmask all interrupt priorities. */ #define portCLEAR_INTERRUPT_MASK() \ { \ portCPU_IRQ_DISABLE(); \ portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \ __asm volatile ( "DSB \n" \ "ISB \n" ); \ portCPU_IRQ_ENABLE(); \ } #define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portBIT_0_SET ( ( uint8_t ) 0x01 ) /* 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /* The space on the stack required to hold the FPU registers. This is 32 64-bit registers, plus a 32-bit status register. */ #define portFPU_REGISTER_WORDS ( ( 32 * 2 ) + 1 ) /*-----------------------------------------------------------*/ /* * Starts the first task executing. This function is necessarily written in * assembly code so is implemented in portASM.s. */ extern void vPortRestoreTaskContext( void ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /* * If the application provides an implementation of vApplicationIRQHandler(), * then it will get called directly without saving the FPU registers on * interrupt entry, and this weak implementation of * vApplicationFPUSafeIRQHandler() is just provided to remove linkage errors - * it should never actually get called so its implementation contains a * call to configASSERT() that will always fail. * * If the application provides its own implementation of * vApplicationFPUSafeIRQHandler() then the implementation of * vApplicationIRQHandler() provided in portASM.S will save the FPU registers * before calling it. * * Therefore, if the application writer wants FPU registers to be saved on * interrupt entry their IRQ handler must be called * vApplicationFPUSafeIRQHandler(), and if the application writer does not want * FPU registers to be saved on interrupt entry their IRQ handler must be * called vApplicationIRQHandler(). */ void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__((weak) ); /*-----------------------------------------------------------*/ /* 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 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 automatically be set to 0 when the first task is started. */ volatile uint32_t ulCriticalNesting = 9999UL; /* 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. */ volatile uint32_t ulPortTaskHasFPUContext = pdFALSE; /* Set to 1 to pend a context switch from an ISR. */ volatile uint32_t ulPortYieldRequired = pdFALSE; /* Counts the interrupt nesting depth. A context switch is only performed if if the nesting depth is 0. */ volatile uint32_t ulPortInterruptNesting = 0UL; /* Used in the asm file. */ __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 ulICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS; __attribute__(( used )) const uint32_t ulMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { /* Setup the initial stack of the task. The stack is set exactly as expected by the portRESTORE_CONTEXT() macro. 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 GDB does not try decoding a non-existent return address. */ *pxTopOfStack = ( StackType_t ) NULL; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) NULL; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) NULL; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portINITIAL_SPSR; if( ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) != 0x00UL ) { /* The task will start in THUMB mode. */ *pxTopOfStack |= portTHUMB_MODE_BIT; } pxTopOfStack--; /* Next the return address, which in this case is the start of the task. */ *pxTopOfStack = ( StackType_t ) pxCode; pxTopOfStack--; /* Next all the registers other than the stack pointer. */ *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* R14 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; /* The task will start with a critical nesting count of 0 as interrupts are enabled. */ *pxTopOfStack = portNO_CRITICAL_NESTING; #if( configUSE_TASK_FPU_SUPPORT == 1 ) { /* The task will start without a floating point context. A task that uses the floating point hardware must call vPortTaskUsesFPU() before executing any floating point instructions. */ pxTopOfStack--; *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; } #elif( configUSE_TASK_FPU_SUPPORT == 2 ) { /* The task will start with a floating point context. Leave enough space for the registers - and ensure they are initialised to 0. */ pxTopOfStack -= portFPU_REGISTER_WORDS; memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) ); pxTopOfStack--; *pxTopOfStack = pdTRUE; ulPortTaskHasFPUContext = pdTRUE; } #else { #error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined. } #endif return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to its caller as there is nothing to return to. If a task wants to exit it should instead call vTaskDelete( NULL ). Artificially force an assert() to be triggered if configASSERT() is defined, then stop here so application writers can catch the error. */ configASSERT( ulPortInterruptNesting == ~0UL ); portDISABLE_INTERRUPTS(); for( ;; ); } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) { uint32_t ulAPSR; #if( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET ); volatile uint8_t ucMaxPriorityValue; /* Determine how many priority bits are implemented in the GIC. Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* Shift to the least significant bits. */ while( ( ucMaxPriorityValue & portBIT_0_SET ) != portBIT_0_SET ) { ucMaxPriorityValue >>= ( uint8_t ) 0x01; } /* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read value. */ configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY ); /* Restore the clobbered interrupt priority register to its original value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* Only continue if the CPU is not in User mode. The CPU must be in a Privileged mode for the scheduler to start. */ __asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) :: "memory" ); ulAPSR &= portAPSR_MODE_BITS_MASK; configASSERT( ulAPSR != portAPSR_USER_MODE ); if( ulAPSR != portAPSR_USER_MODE ) { /* Only continue if the binary point value is set to its lowest possible setting. See the comments in vPortValidateInterruptPriority() below for more information. */ configASSERT( ( 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 not execute while the scheduler is being started. Interrupts are automatically turned back on in the CPU when the first task starts executing. */ portCPU_IRQ_DISABLE(); /* Start the timer that generates the tick ISR. */ configSETUP_TICK_INTERRUPT(); /* Start the first task executing. */ vPortRestoreTaskContext(); } } /* 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 possible value. prvTaskExitError() is referenced to prevent a compiler warning about it being defined but not referenced in the case that the user defines their own exit address. */ ( void ) prvTaskExitError; return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { /* Mask interrupts up to the max syscall interrupt priority. */ ulPortSetInterruptMask(); /* Now interrupts are disabled ulCriticalNesting can be accessed directly. Increment ulCriticalNesting to keep a count of how many times portENTER_CRITICAL() has been called. */ ulCriticalNesting++; /* 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 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 assert function also uses a critical section. */ if( ulCriticalNesting == 1 ) { configASSERT( ulPortInterruptNesting == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { if( ulCriticalNesting > portNO_CRITICAL_NESTING ) { /* Decrement the nesting count as the critical section is being exited. */ ulCriticalNesting--; /* If the nesting level has reached zero then all interrupt priorities must be re-enabled. */ if( ulCriticalNesting == portNO_CRITICAL_NESTING ) { /* Critical nesting has reached zero so all interrupt priorities should be unmasked. */ portCLEAR_INTERRUPT_MASK(); } } } /*-----------------------------------------------------------*/ void FreeRTOS_Tick_Handler( void ) { /* Set interrupt mask before altering scheduler structures. The tick 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 necessary to turn off interrupts in the CPU itself while the ICCPMR is being updated. */ portCPU_IRQ_DISABLE(); portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); __asm volatile ( "dsb \n" "isb \n" ::: "memory" ); portCPU_IRQ_ENABLE(); /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { ulPortYieldRequired = pdTRUE; } /* Ensure all interrupt priorities are active again. */ portCLEAR_INTERRUPT_MASK(); configCLEAR_TICK_INTERRUPT(); } /*-----------------------------------------------------------*/ #if( configUSE_TASK_FPU_SUPPORT != 2 ) void vPortTaskUsesFPU( void ) { uint32_t ulInitialFPSCR = 0; /* 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). */ ulPortTaskHasFPUContext = pdTRUE; /* Initialise the floating point status register. */ __asm volatile ( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) : "memory" ); } #endif /* configUSE_TASK_FPU_SUPPORT */ /*-----------------------------------------------------------*/ void vPortClearInterruptMask( uint32_t ulNewMaskValue ) { if( ulNewMaskValue == pdFALSE ) { portCLEAR_INTERRUPT_MASK(); } } /*-----------------------------------------------------------*/ uint32_t ulPortSetInterruptMask( void ) { uint32_t ulReturn; /* Interrupt in the CPU must be turned off while the ICCPMR is being updated. */ portCPU_IRQ_DISABLE(); if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ) { /* Interrupts were already masked. */ ulReturn = pdTRUE; } else { ulReturn = pdFALSE; portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); __asm volatile ( "dsb \n" "isb \n" ::: "memory" ); } portCPU_IRQ_ENABLE(); return ulReturn; } /*-----------------------------------------------------------*/ #if( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { /* The following assertion will fail if a service routine (ISR) for an interrupt that has been assigned a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API function. ISR safe FreeRTOS API functions must *only* be called from interrupts that have been assigned a priority at or below configMAX_SYSCALL_INTERRUPT_PRIORITY. Numerically low interrupt priority numbers represent logically high interrupt priorities, therefore the priority of the interrupt must be set to a value equal to or numerically *higher* than configMAX_SYSCALL_INTERRUPT_PRIORITY. FreeRTOS maintains separate thread and ISR API functions to ensure interrupt entry is as fast and simple as possible. */ configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); /* Priority grouping: The interrupt controller (GIC) allows the bits that define each interrupt's priority to be split between bits that define the interrupt's pre-emption priority bits and bits that define the interrupt's sub-priority. For simplicity all bits must be defined to be pre-emption priority bits. The following assertion will fail if this is not the case (if some bits represent a sub-priority). 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 possible value (which may be above 0). */ configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); } #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) { ( void ) ulICCIAR; configASSERT( ( volatile void * ) NULL ); } ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CA9/portASM.S ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ .eabi_attribute Tag_ABI_align_preserved, 1 .text .arm .set SYS_MODE, 0x1f .set SVC_MODE, 0x13 .set IRQ_MODE, 0x12 /* Hardware registers. */ .extern ulICCIAR .extern ulICCEOIR .extern ulICCPMR /* Variables and functions. */ .extern ulMaxAPIPriorityMask .extern _freertos_vector_table .extern pxCurrentTCB .extern vTaskSwitchContext .extern vApplicationIRQHandler .extern ulPortInterruptNesting .extern ulPortTaskHasFPUContext .global FreeRTOS_IRQ_Handler .global FreeRTOS_SWI_Handler .global vPortRestoreTaskContext .macro portSAVE_CONTEXT /* Save the LR and SPSR onto the system mode stack before switching to system mode to save the remaining system mode registers. */ SRSDB sp!, #SYS_MODE CPS #SYS_MODE PUSH {R0-R12, R14} /* Push the critical nesting count. */ LDR R2, ulCriticalNestingConst LDR R1, [R2] PUSH {R1} /* Does the task have a floating point context that needs saving? If ulPortTaskHasFPUContext is 0 then no. */ LDR R2, ulPortTaskHasFPUContextConst LDR R3, [R2] CMP R3, #0 /* Save the floating point context, if any. */ FMRXNE R1, FPSCR VPUSHNE {D0-D15} VPUSHNE {D16-D31} PUSHNE {R1} /* Save ulPortTaskHasFPUContext itself. */ PUSH {R3} /* Save the stack pointer in the TCB. */ LDR R0, pxCurrentTCBConst LDR R1, [R0] STR SP, [R1] .endm ; /**********************************************************************/ .macro portRESTORE_CONTEXT /* Set the SP to point to the stack of the task being restored. */ LDR R0, pxCurrentTCBConst LDR R1, [R0] LDR SP, [R1] /* Is there a floating point context to restore? If the restored ulPortTaskHasFPUContext is zero then no. */ LDR R0, ulPortTaskHasFPUContextConst POP {R1} STR R1, [R0] CMP R1, #0 /* Restore the floating point context, if any. */ POPNE {R0} VPOPNE {D16-D31} VPOPNE {D0-D15} VMSRNE FPSCR, R0 /* Restore the critical section nesting depth. */ LDR R0, ulCriticalNestingConst POP {R1} STR R1, [R0] /* Ensure the priority mask is correct for the critical nesting depth. */ LDR R2, ulICCPMRConst LDR R2, [R2] CMP R1, #0 MOVEQ R4, #255 LDRNE R4, ulMaxAPIPriorityMaskConst LDRNE R4, [R4] STR R4, [R2] /* Restore all system mode registers other than the SP (which is already being used). */ POP {R0-R12, R14} /* Return to the task code, loading CPSR on the way. */ RFEIA sp! .endm /****************************************************************************** * SVC handler is used to start the scheduler. *****************************************************************************/ .align 4 .type FreeRTOS_SWI_Handler, %function FreeRTOS_SWI_Handler: /* Save the context of the current task and select a new task to run. */ portSAVE_CONTEXT LDR R0, vTaskSwitchContextConst BLX R0 portRESTORE_CONTEXT /****************************************************************************** * vPortRestoreTaskContext is used to start the scheduler. *****************************************************************************/ .type vPortRestoreTaskContext, %function vPortRestoreTaskContext: /* Switch to system mode. */ CPS #SYS_MODE portRESTORE_CONTEXT .align 4 .type FreeRTOS_IRQ_Handler, %function FreeRTOS_IRQ_Handler: /* Return to the interrupted instruction. */ SUB lr, lr, #4 /* Push the return address and SPSR. */ PUSH {lr} MRS lr, SPSR PUSH {lr} /* Change to supervisor mode to allow reentry. */ CPS #SVC_MODE /* Push used registers. */ PUSH {r0-r4, r12} /* Increment nesting count. r3 holds the address of ulPortInterruptNesting for future use. r1 holds the original ulPortInterruptNesting value for future use. */ LDR r3, ulPortInterruptNestingConst LDR r1, [r3] ADD r4, r1, #1 STR r4, [r3] /* Read value from the interrupt acknowledge register, which is stored in r0 for future parameter and interrupt clearing use. */ LDR r2, ulICCIARConst LDR r2, [r2] LDR r0, [r2] /* Ensure bit 2 of the stack pointer is clear. r2 holds the bit 2 value for future use. _RB_ Does this ever actually need to be done provided the start of the stack is 8-byte aligned? */ MOV r2, sp AND r2, r2, #4 SUB sp, sp, r2 /* Call the interrupt handler. r4 pushed to maintain alignment. */ PUSH {r0-r4, lr} LDR r1, vApplicationIRQHandlerConst BLX r1 POP {r0-r4, lr} ADD sp, sp, r2 CPSID i DSB ISB /* Write the value read from ICCIAR to ICCEOIR. */ LDR r4, ulICCEOIRConst LDR r4, [r4] STR r0, [r4] /* Restore the old nesting count. */ STR r1, [r3] /* A context switch is never performed if the nesting count is not 0. */ CMP r1, #0 BNE exit_without_switch /* Did the interrupt request a context switch? r1 holds the address of ulPortYieldRequired and r0 the value of ulPortYieldRequired for future use. */ LDR r1, =ulPortYieldRequired LDR r0, [r1] CMP r0, #0 BNE switch_before_exit exit_without_switch: /* No context switch. Restore used registers, LR_irq and SPSR before returning. */ POP {r0-r4, r12} CPS #IRQ_MODE POP {LR} MSR SPSR_cxsf, LR POP {LR} MOVS PC, LR switch_before_exit: /* A context swtich is to be performed. Clear the context switch pending flag. */ MOV r0, #0 STR r0, [r1] /* Restore used registers, LR-irq and SPSR before saving the context to the task stack. */ POP {r0-r4, r12} CPS #IRQ_MODE POP {LR} MSR SPSR_cxsf, LR POP {LR} portSAVE_CONTEXT /* Call the function that selects the new task to execute. vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD instructions, or 8 byte aligned stack allocated data. LR does not need saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. */ LDR R0, vTaskSwitchContextConst BLX R0 /* Restore the context of, and branch to, the task selected to execute next. */ portRESTORE_CONTEXT /****************************************************************************** * If the application provides an implementation of vApplicationIRQHandler(), * then it will get called directly without saving the FPU registers on * interrupt entry, and this weak implementation of * vApplicationIRQHandler() will not get called. * * If the application provides its own implementation of * vApplicationFPUSafeIRQHandler() then this implementation of * vApplicationIRQHandler() will be called, save the FPU registers, and then * call vApplicationFPUSafeIRQHandler(). * * Therefore, if the application writer wants FPU registers to be saved on * interrupt entry their IRQ handler must be called * vApplicationFPUSafeIRQHandler(), and if the application writer does not want * FPU registers to be saved on interrupt entry their IRQ handler must be * called vApplicationIRQHandler(). *****************************************************************************/ .align 4 .weak vApplicationIRQHandler .type vApplicationIRQHandler, %function vApplicationIRQHandler: PUSH {LR} FMRX R1, FPSCR VPUSH {D0-D15} VPUSH {D16-D31} PUSH {R1} LDR r1, vApplicationFPUSafeIRQHandlerConst BLX r1 POP {R0} VPOP {D16-D31} VPOP {D0-D15} VMSR FPSCR, R0 POP {PC} ulICCIARConst: .word ulICCIAR ulICCEOIRConst: .word ulICCEOIR ulICCPMRConst: .word ulICCPMR pxCurrentTCBConst: .word pxCurrentTCB ulCriticalNestingConst: .word ulCriticalNesting ulPortTaskHasFPUContextConst: .word ulPortTaskHasFPUContext ulMaxAPIPriorityMaskConst: .word ulMaxAPIPriorityMask vTaskSwitchContextConst: .word vTaskSwitchContext vApplicationIRQHandlerConst: .word vApplicationIRQHandler ulPortInterruptNestingConst: .word ulPortInterruptNesting vApplicationFPUSafeIRQHandlerConst: .word vApplicationFPUSafeIRQHandler .end ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CA9/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 /*-----------------------------------------------------------*/ /* Hardware specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Task utilities. */ /* Called at the end of an ISR that can cause a context switch. */ #define portEND_SWITCHING_ISR( xSwitchRequired )\ { \ extern uint32_t ulPortYieldRequired; \ \ if( xSwitchRequired != pdFALSE ) \ { \ ulPortYieldRequired = pdTRUE; \ } \ } #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD() __asm volatile ( "SWI 0" ::: "memory" ); /*----------------------------------------------------------- * Critical section control *----------------------------------------------------------*/ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); extern uint32_t ulPortSetInterruptMask( void ); extern void vPortClearInterruptMask( uint32_t ulNewMaskValue ); extern void vPortInstallFreeRTOSVectorTable( void ); /* These macros do not globally disable/enable interrupts. They do mask off interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */ #define portENTER_CRITICAL() vPortEnterCritical(); #define portEXIT_CRITICAL() vPortExitCritical(); #define portDISABLE_INTERRUPTS() ulPortSetInterruptMask() #define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 ) #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x) /*-----------------------------------------------------------*/ /* 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 macros is used. */ #define portTASK_FUNCTION_PROTO( 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 handler for whichever peripheral is used to generate the RTOS tick. */ void FreeRTOS_Tick_Handler( void ); /* 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 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 by default. */ #if( configUSE_TASK_FPU_SUPPORT != 2 ) void vPortTaskUsesFPU( void ); #else /* Each task has an FPU context already, so define this function away to nothing to prevent it being called accidentally. */ #define vPortTaskUsesFPU() #endif #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() #define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) #define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL ) /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* configASSERT */ #define portNOP() __asm volatile( "NOP" ) #define portINLINE __inline #ifdef __cplusplus } /* extern C */ #endif /* The number of bits to shift for an interrupt priority is dependent on the number of bits implemented by the interrupt controller. */ #if configUNIQUE_INTERRUPT_PRIORITIES == 16 #define portPRIORITY_SHIFT 4 #define portMAX_BINARY_POINT_VALUE 3 #elif configUNIQUE_INTERRUPT_PRIORITIES == 32 #define portPRIORITY_SHIFT 3 #define portMAX_BINARY_POINT_VALUE 2 #elif configUNIQUE_INTERRUPT_PRIORITIES == 64 #define portPRIORITY_SHIFT 2 #define portMAX_BINARY_POINT_VALUE 1 #elif configUNIQUE_INTERRUPT_PRIORITIES == 128 #define portPRIORITY_SHIFT 1 #define portMAX_BINARY_POINT_VALUE 0 #elif configUNIQUE_INTERRUPT_PRIORITIES == 256 #define portPRIORITY_SHIFT 0 #define portMAX_BINARY_POINT_VALUE 0 #else #error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware #endif /* Interrupt controller access addresses. */ #define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 ) #define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C ) #define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 ) #define portICCBPR_BINARY_POINT_OFFSET ( 0x08 ) #define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 ) #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 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 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 portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) ) #define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM0/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM0 port. *----------------------------------------------------------*/ /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) /* The systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /* A fiddle factor to estimate the number of SysTick counts that would have * occurred while the SysTick counter is stopped during tickless idle * calculations. */ #ifndef portMISSED_COUNTS_FACTOR #define portMISSED_COUNTS_FACTOR ( 94UL ) #endif /* Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /* 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 * debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ); /* * Exception handlers. */ void xPortPendSVHandler( void ) __attribute__( ( naked ) ); void xPortSysTickHandler( void ); void vPortSVCHandler( void ); /* * Start first task is a separate function so it can be tested in isolation. */ static void vPortStartFirstTask( void ) __attribute__( ( naked ) ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* Each task maintains its own interrupt status in the critical nesting * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /*-----------------------------------------------------------*/ /* * The number of SysTick increments that make up one tick period. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulTimerCountsForOneTick = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * The maximum number of tick periods that can be suppressed is limited by the * 24 bit resolution of the SysTick timer. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t xMaximumPossibleSuppressedTicks = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Compensate for the CPU cycles that pass while the SysTick is stopped (low * power functionality only. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 8; /* R11..R4. */ return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). * * Artificially force an assert() to be triggered if configASSERT() is * defined, then stop here so application writers can catch the error. */ configASSERT( uxCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being defined * but never called. ulDummy is used purely to quieten other warnings * about code appearing after this function is called - making ulDummy * volatile makes the compiler think the function could return and * therefore not output an 'unreachable code' warning for code that appears * after it. */ } } /*-----------------------------------------------------------*/ void vPortSVCHandler( void ) { /* This function is no longer used, but retained for backward * compatibility. */ } /*-----------------------------------------------------------*/ void vPortStartFirstTask( void ) { /* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector * table offset register that can be used to locate the initial stack value. * Not all M0 parts have the application vector table at address 0. */ __asm volatile ( " .syntax unified \n" " ldr r2, pxCurrentTCBConst2 \n"/* Obtain location of pxCurrentTCB. */ " ldr r3, [r2] \n" " ldr r0, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. */ " 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. */ " movs r0, #2 \n"/* Switch to the psp stack. */ " msr CONTROL, r0 \n" " isb \n" " pop {r0-r5} \n"/* Pop the registers that are saved automatically. */ " mov lr, r5 \n"/* lr is now in r5. */ " pop {r3} \n"/* Return address is now in r3. */ " pop {r2} \n"/* Pop and discard XPSR. */ " 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. */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB " ); } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Start the first task. */ vPortStartFirstTask(); /* Should never get here as the tasks will now be executing! Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimisation does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortYield( void ) { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is completely * within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); uxCriticalNesting++; __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ uint32_t ulSetInterruptMaskFromISR( void ) { __asm volatile ( " mrs r0, PRIMASK \n" " cpsid i \n" " bx lr " ::: "memory" ); } /*-----------------------------------------------------------*/ void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) { __asm volatile ( " msr PRIMASK, r0 \n" " bx lr " ::: "memory" ); } /*-----------------------------------------------------------*/ void xPortPendSVHandler( void ) { /* This is a naked function. */ __asm volatile ( " .syntax unified \n" " mrs r0, psp \n" " \n" " ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */ " ldr r2, [r3] \n" " \n" " subs r0, r0, #32 \n"/* Make space for the remaining low registers. */ " str r0, [r2] \n"/* Save the new top of stack. */ " stmia r0!, {r4-r7} \n"/* Store the low registers that are not saved automatically. */ " mov r4, r8 \n"/* Store the high registers. */ " mov r5, r9 \n" " mov r6, r10 \n" " mov r7, r11 \n" " stmia r0!, {r4-r7} \n" " \n" " push {r3, r14} \n" " cpsid i \n" " bl vTaskSwitchContext \n" " cpsie i \n" " pop {r2, r3} \n"/* lr goes in r3. r2 now holds tcb pointer. */ " \n" " ldr r1, [r2] \n" " 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. */ " ldmia r0!, {r4-r7} \n"/* Pop the high registers. */ " mov r8, r4 \n" " mov r9, r5 \n" " mov r10, r6 \n" " mov r11, r7 \n" " \n" " msr psp, r0 \n"/* Remember the new top of stack for the task. */ " \n" " subs r0, r0, #32 \n"/* Go back for the low registers that are not automatically restored. */ " ldmia r0!, {r4-r7} \n"/* Pop low registers. */ " \n" " bx r3 \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB " ); } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ /* * Setup the systick timer to generate the tick interrupts at the required * frequency. */ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); } /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM0/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ extern void vPortYield( void ); #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portYIELD() vPortYield() #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); extern uint32_t ulSetInterruptMaskFromISR( void ) __attribute__( ( naked ) ); extern void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__( ( naked ) ); #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x ) #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portNOP() #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23/non_secure/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /* Portasm includes. */ #include "portasm.h" #if ( configENABLE_TRUSTZONE == 1 ) /* Secure components includes. */ #include "secure_context.h" #include "secure_init.h" #endif /* configENABLE_TRUSTZONE */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /** * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS * on the secure side. The following are the valid configuration seetings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 * * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 * * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 */ #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. #endif /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the SCB. */ #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the FPU. */ #define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) #define portMPU_RLAR_REGION_ENABLE ( 1UL ) /* Enable privileged access to unmapped region. */ #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /*-----------------------------------------------------------*/ /** * @brief The maximum 24-bit number. * * It is needed because the systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /** * @brief A fiddle factor to estimate the number of SysTick counts that would * have occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) /** * @brief Initial EXC_RETURN value. * * FF FF FF FD * 1111 1111 1111 1111 1111 1111 1111 1101 * * Bit[6] - 1 --> The exception was taken from the Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 1 --> The exception was taken to the Secure state. */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else /** * @brief Initial EXC_RETURN value. * * FF FF FF BC * 1111 1111 1111 1111 1111 1111 1011 1100 * * Bit[6] - 0 --> The exception was taken from the Non-Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 0 --> The exception was taken to the Non-Secure state. */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ /** * @brief CONTROL register privileged bit mask. * * Bit[0] in CONTROL register tells the privilege: * Bit[0] = 0 ==> The task is privileged. * Bit[0] = 1 ==> The task is not privileged. */ #define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) /** * @brief Initial CONTROL register values. */ #define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) #define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) /** * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /** * @brief 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /** * @brief If portPRELOAD_REGISTERS then registers will be given an initial value * when a task is created. This helps in debugging at the cost of code size. */ #define portPRELOAD_REGISTERS 1 /** * @brief A task is created without a secure context, and must call * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes * any secure calls. */ #define portNO_SECURE_CONTEXT 0 /*-----------------------------------------------------------*/ /** * @brief Used to catch tasks that attempt to return from their implementing * function. */ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) /** * @brief Setup the Memory Protection Unit (MPU). */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) /** * @brief Setup the Floating Point Unit (FPU). */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ /** * @brief Setup the timer to generate the tick interrupts. * * The implementation in this file is weak to allow application writers to * change the timer used to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /** * @brief Checks whether the current execution context is interrupt. * * @return pdTRUE if the current execution context is interrupt, pdFALSE * otherwise. */ BaseType_t xPortIsInsideInterrupt( void ); /** * @brief Yield the processor. */ void vPortYield( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ void vPortExitCritical( void ) PRIVILEGED_FUNCTION; /** * @brief SysTick handler. */ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; /** * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. */ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Saved as part of the task context to indicate which context the * task is using on the secure side. */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ #if ( configUSE_TICKLESS_IDLE == 1 ) /** * @brief The number of SysTick increments that make up one tick period. */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; /** * @brief The maximum number of tick periods that can be suppressed is * limited by the 24 bit resolution of the SysTick timer. */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; /** * @brief Compensate for the CPU cycles that pass while the SysTick is * stopped (low power functionality only). */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). Artificially force an assert() * to be triggered if configASSERT() is defined, then stop here so * application writers can catch the error. */ configASSERT( ulCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being * defined but never called. ulDummy is used purely to quieten other * warnings about code appearing after this function is called - making * ulDummy volatile makes the compiler think the function could return * and therefore not output an 'unreachable code' warning for code that * appears after it. */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; extern uint32_t * __unprivileged_flash_start__; extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* if defined( __ARMCC_VERSION ) */ /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; extern uint32_t __unprivileged_flash_start__[]; extern uint32_t __unprivileged_flash_end__[]; extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check that the MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* MAIR0 - Index 0. */ portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); /* MAIR0 - Index 1. */ portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* Setup privileged flash as Read Only so that privileged tasks can * read it but not modify. */ portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged flash as Read Only by both privileged and * unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged syscalls flash as Read Only by both privileged * and unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup RAM containing kernel data for privileged access only. */ portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Enable mem fault. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; /* Enable MPU with privileged background access i.e. unmapped * regions have privileged access. */ portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) { /* Enable non-secure access to the FPU. */ SecureInit_EnableNSFPUAccess(); } #endif /* configENABLE_TRUSTZONE */ /* CP10 = 11 ==> Full access to FPU i.e. both privileged and * unprivileged code should be able to access FPU. CP11 should be * programmed to the same value as CP10. */ *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) ); /* ASPEN = 1 ==> Hardware should automatically preserve floating point * context on exception entry and restore on exception return. * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ void vPortYield( void ) /* PRIVILEGED_FUNCTION */ { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ { portDISABLE_INTERRUPTS(); ulCriticalNesting++; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ { configASSERT( ulCriticalNesting ); ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { #if ( configENABLE_MPU == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ #endif /* configENABLE_MPU */ uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) uint32_t ulR0, ulR1; extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ #endif /* configENABLE_TRUSTZONE */ uint8_t ucSVCNumber; /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ ulPC = pulCallerStackAddress[ 6 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { #if ( configENABLE_TRUSTZONE == 1 ) case portSVC_ALLOCATE_SECURE_CONTEXT: /* R0 contains the stack size passed as parameter to the * vPortAllocateSecureContext function. */ ulR0 = pulCallerStackAddress[ 0 ]; #if ( configENABLE_MPU == 1 ) { /* Read the CONTROL register value. */ __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); /* The task that raised the SVC is privileged if Bit[0] * in the CONTROL register is 0. */ ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: /* R0 contains TCB being freed and R1 contains the secure * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) { /* De-prioritize the non-secure exceptions so that the * non-secure pendSV runs at the lowest priority. */ SecureInit_DePrioritizeNSExceptions(); /* Initialize the secure context management system. */ SecureContext_Init(); } #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_FPU == 1 ) { /* Setup the Floating Point Unit (FPU). */ prvSetupFPU(); } #endif /* configENABLE_FPU */ /* Setup the context of the first task so that the first task starts * executing. */ vRestoreContextOfFirstTask(); break; #if ( configENABLE_MPU == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the svc was raised from any of * the system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { vRaisePrivilege(); } break; #endif /* configENABLE_MPU */ default: /* Incorrect SVC call. */ configASSERT( pdFALSE ); } } /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #if ( configENABLE_MPU == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /* *INDENT-ON* */ { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #endif /* portPRELOAD_REGISTERS */ return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ prvSetupMPU(); } #endif /* configENABLE_MPU */ /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; /* Start the first task. */ vStartFirstTask(); /* Should never get here as the tasks will now be executing. Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* Setup MAIR0. */ xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ if( ulStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged * SRAM is already protected using an MPU region and ARMv8-M does * not allow overlapping MPU regions. */ if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) { xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; } else { /* Define the region that allows access to the stack. */ ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); } } /* User supplied configurable regions. */ for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) { /* If xRegions is NULL i.e. the task has not specified any MPU * region, the else part ensures that all the configurable MPU * regions are invalidated. */ if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) { /* Translate the generic region definition contained in xRegions * into the ARMv8 specific MPU settings that are then stored in * xMPUSettings. */ ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; /* Start address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ); /* RO/RW. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); } else { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); } /* XN. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); } /* End Address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { /* Attr1 in MAIR0 is configured as device memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; } else { /* Attr0 in MAIR0 is configured as normal memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; } } else { /* Invalidate the region. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; } lIndex++; } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. Interrupt Program * Status Register (IPSR) holds the exception number of the currently-executing * exception or zero for Thread mode.*/ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23/non_secure/portasm.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION * is defined correctly and privileged functions are placed in correct sections. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Portasm includes. */ #include "portasm.h" /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #if ( configENABLE_FPU == 1 ) #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " movs r5, #1 \n"/* r5 = 1. */ " bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ " str r4, [r2] \n"/* Disable MPU. */ " \n" " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r4, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ " movs r5, #4 \n"/* r5 = 4. */ " str r5, [r2] \n"/* Program RNR = 4. */ " ldmia r3!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */ " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ " stmia r4!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */ " movs r5, #5 \n"/* r5 = 5. */ " str r5, [r2] \n"/* Program RNR = 5. */ " ldmia r3!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */ " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ " stmia r4!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */ " movs r5, #6 \n"/* r5 = 6. */ " str r5, [r2] \n"/* Program RNR = 6. */ " ldmia r3!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */ " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ " stmia r4!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */ " movs r5, #7 \n"/* r5 = 7. */ " str r5, [r2] \n"/* Program RNR = 7. */ " ldmia r3!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */ " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ " stmia r4!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */ " \n" " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " movs r5, #1 \n"/* r5 = 1. */ " orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ " str r4, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ " ldr r5, xSecureContextConst2 \n" " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ " msr control, r3 \n"/* Set this task's CONTROL value. */ " 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. */ " isb \n" " bx r4 \n"/* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, xSecureContextConst2 \n" " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ " movs r1, #2 \n"/* r1 = 2. */ " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ " 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. */ " isb \n" " bx r3 \n"/* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" "xSecureContextConst2: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst2: .word 0xe000ed94 \n" "xMAIR0Const2: .word 0xe000edc0 \n" "xRNRConst2: .word 0xe000ed98 \n" "xRBARConst2: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " movs r1, #1 \n"/* r1 = 1. */ " 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. */ " movs r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ " bx lr \n"/* Return. */ " running_privileged: \n" " movs r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n"/* Return. */ " \n" " .align 4 \n" ::: "r0", "r1", "memory" ); } /*-----------------------------------------------------------*/ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* Read the CONTROL register. */ " movs r1, #1 \n"/* r1 = 1. */ " bics r0, r1 \n"/* Clear the bit 0. */ " msr control, r0 \n"/* Write back the new CONTROL value. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "r1", "memory" ); } /*-----------------------------------------------------------*/ void vResetPrivilege( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " movs r1, #1 \n"/* r1 = 1. */ " orrs r0, r1 \n"/* r0 = r0 | r1. */ " msr control, r0 \n"/* CONTROL = r0. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "r1", "memory" ); } /*-----------------------------------------------------------*/ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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"/* The first entry in vector table is stack pointer. */ " msr msp, r0 \n"/* Set the MSP back to the start of the stack. */ " cpsie i \n"/* Globally enable interrupts. */ " dsb \n" " isb \n" " svc %0 \n"/* System call to start the first task. */ " nop \n" " \n" " .align 4 \n" "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } /*-----------------------------------------------------------*/ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, PRIMASK \n" " cpsid i \n" " bx lr \n" ::: "memory" ); } /*-----------------------------------------------------------*/ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " msr PRIMASK, r0 \n" " bx lr \n" ::: "memory" ); } /*-----------------------------------------------------------*/ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" " 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 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.*/ " mrs r2, psp \n"/* Read PSP in r2. */ " \n" " cbz r0, save_ns_context \n"/* No secure context to save. */ " push {r0-r2, r14} \n" " bl SecureContext_SaveContext \n"/* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r0-r3} \n"/* LR is now in 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. */ " 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. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ " str r2, [r1] \n"/* Save the new top of stack in TCB. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r3, control \n"/* r3 = CONTROL. */ " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ " 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. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ " b select_next_task \n" " \n" " save_ns_context: \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ " str r2, [r1] \n"/* Save the new top of stack in TCB. */ " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ " stmia r2!, {r4-r7} \n"/* Store the low registers that are not saved automatically. */ " mov r4, r8 \n"/* r4 = r8. */ " mov r5, r9 \n"/* r5 = r9. */ " mov r6, r10 \n"/* r6 = r10. */ " mov r7, r11 \n"/* r7 = r11. */ " stmia r2!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r3, control \n"/* r3 = CONTROL. */ " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ " subs r2, r2, #48 \n"/* r2 = r2 - 48. */ " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ " 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. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " stmia r2!, {r0, r1, r3-r7} \n"/* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ " mov r4, r8 \n"/* r4 = r8. */ " mov r5, r9 \n"/* r5 = r9. */ " mov r6, r10 \n"/* r6 = r10. */ " mov r7, r11 \n"/* r7 = r11. */ " stmia r2!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ #endif /* configENABLE_MPU */ " \n" " select_next_task: \n" " cpsid i \n" " bl vTaskSwitchContext \n" " cpsie i \n" " \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ " movs r5, #1 \n"/* r5 = 1. */ " bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ " str r4, [r3] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ " str r4, [r3] \n"/* Program MAIR0. */ " ldr r4, xRNRConst \n"/* r4 = 0xe000ed98 [Location of RNR]. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " movs r5, #4 \n"/* r5 = 4. */ " str r5, [r4] \n"/* Program RNR = 4. */ " ldmia r1!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */ " movs r5, #5 \n"/* r5 = 5. */ " str r5, [r4] \n"/* Program RNR = 5. */ " ldmia r1!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */ " movs r5, #6 \n"/* r5 = 6. */ " str r5, [r4] \n"/* Program RNR = 6. */ " ldmia r1!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */ " movs r5, #7 \n"/* r5 = 7. */ " str r5, [r4] \n"/* Program RNR = 7. */ " ldmia r1!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */ " \n" " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ " movs r5, #1 \n"/* r5 = 1. */ " orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ " str r4, [r3] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ " mov lr, r4 \n"/* LR = r4. */ " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( 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. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " push {r2, r4} \n" " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r2, r4} \n" " 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. */ " 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. */ " bx lr \n" #else /* configENABLE_MPU */ " 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. */ " mov lr, r4 \n"/* LR = r4. */ " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( 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. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " push {r2, r4} \n" " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r2, r4} \n" " 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. */ " 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. */ " bx lr \n" #endif /* configENABLE_MPU */ " \n" " restore_ns_context: \n" " adds r2, r2, #16 \n"/* Move to the high registers. */ " ldmia r2!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ " mov r8, r4 \n"/* r8 = r4. */ " mov r9, r5 \n"/* r9 = r5. */ " mov r10, r6 \n"/* r10 = r6. */ " mov r11, r7 \n"/* r11 = r7. */ " msr psp, r2 \n"/* Remember the new top of stack for the task. */ " subs r2, r2, #32 \n"/* Go back to the low registers. */ " ldmia r2!, {r4-r7} \n"/* Restore the low registers that are not automatically restored. */ " bx lr \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" "xSecureContextConst: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst: .word 0xe000ed94 \n" "xMAIR0Const: .word 0xe000edc0 \n" "xRNRConst: .word 0xe000ed98 \n" "xRBARConst: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } /*-----------------------------------------------------------*/ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " movs r0, #4 \n" " mov r1, lr \n" " tst r0, r1 \n" " beq stacking_used_msp \n" " mrs r0, psp \n" " ldr r2, svchandler_address_const \n" " bx r2 \n" " stacking_used_msp: \n" " mrs r0, msp \n" " ldr r2, svchandler_address_const \n" " bx r2 \n" " \n" " .align 4 \n" "svchandler_address_const: .word vPortSVCHandler_C \n" ); } /*-----------------------------------------------------------*/ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " svc %0 \n"/* Secure context is allocated in the supervisor call. */ " bx lr \n"/* Return. */ ::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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. */ " cmp r1, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */ " bne free_secure_context \n"/* Branch if r1 != 0. */ " bx lr \n"/* There is no secure context (xSecureContext is NULL). */ " free_secure_context: \n" " svc %0 \n"/* Secure context is freed in the supervisor call. */ " bx lr \n"/* Return. */ ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23/non_secure/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORT_ASM_H__ #define __PORT_ASM_H__ /* Scheduler includes. */ #include "FreeRTOS.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /** * @brief Restore the context of the first task so that the first task starts * executing. */ void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * * @note This is a privileged function and should only be called from the kenrel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Starts the first task. */ void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Disables interrupts. */ uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Enables interrupts. */ void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief PendSV Exception handler. */ void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief SVC Handler. */ void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Allocate a Secure context for the calling task. * * @param[in] ulSecureStackSize The size of the stack to be allocated on the * secure side for the calling task. */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); /** * @brief Free the task's secure context. * * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. */ void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* __PORT_ASM_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23/non_secure/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M23" #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACROCOMMON_H #define PORTMACROCOMMON_H #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_FPU #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. #endif /* configENABLE_FPU */ #ifndef configENABLE_MPU #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. #endif /* configENABLE_MPU */ #ifndef configENABLE_TRUSTZONE #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ /** * @brief Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif #define portHAS_STACK_OVERFLOW_CHECKING 1 /*-----------------------------------------------------------*/ /** * @brief Extern declarations. */ extern BaseType_t xPortIsInsideInterrupt( void ); extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; #if ( configENABLE_TRUSTZONE == 1 ) extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_MPU == 1 ) extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief MPU specific constants. */ #if ( configENABLE_MPU == 1 ) #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #else #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* MPU regions. */ #define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_RAM_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ /* Device memory attributes used in MPU_MAIR registers. * * 8-bit values encoded as follows: * Bit[7:4] - 0000 - Device Memory * Bit[3:2] - 00 --> Device-nGnRnE * 01 --> Device-nGnRE * 10 --> Device-nGRE * 11 --> Device-GRE * Bit[1:0] - 00, Reserved. */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ /* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ /* Attributes used in MPU_RBAR registers. */ #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ /** * @brief Settings to define an MPU region. */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */ } MPURegionSettings_t; /** * @brief MPU settings as stored in the TCB. */ typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ } xMPU_SETTINGS; /*-----------------------------------------------------------*/ /** * @brief SVC numbers. */ #define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 /*-----------------------------------------------------------*/ /** * @brief Scheduler utilities. */ #define portYIELD() vPortYield() #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /** * @brief Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /** * @brief Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Allocate a secure context for the task. * * 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 context before it calls any secure function. * * @param[in] ulSecureStackSize The size of the secure stack to be allocated. */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) /** * @brief Called when a task is deleted to delete the task's secure context, * if it has one. * * @param[in] pxTCB The TCB of the task being deleted. */ #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. * * 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, * the privilege is not raised. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() #else #define portIS_PRIVILEGED() #define portRAISE_PRIVILEGE() #define portRESET_PRIVILEGE() #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief Barriers. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACROCOMMON_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23/secure/secure_context.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Secure context includes. */ #include "secure_context.h" /* Secure heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief CONTROL value for privileged tasks. * * Bit[0] - 0 --> Thread mode is privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_PRIVILEGED 0x02 /** * @brief CONTROL value for un-privileged tasks. * * Bit[0] - 1 --> Thread mode is un-privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 /** * @brief Size of stack seal values in bytes. */ #define securecontextSTACK_SEAL_SIZE 8 /** * @brief Stack seal value as recommended by ARM. */ #define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5 /** * @brief Maximum number of secure contexts. */ #ifndef secureconfigMAX_SECURE_CONTEXTS #define secureconfigMAX_SECURE_CONTEXTS 8UL #endif /*-----------------------------------------------------------*/ /** * @brief Pre-allocated array of secure contexts. */ SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ]; /*-----------------------------------------------------------*/ /** * @brief Get a free secure context for a task from the secure context pool (xSecureContexts). * * This function ensures that only one secure context is allocated for a task. * * @param[in] pvTaskHandle The task handle for which the secure context is allocated. * * @return Index of a free secure context in the xSecureContexts array. */ static uint32_t ulGetSecureContext( void * pvTaskHandle ); /** * @brief Return the secure context to the secure context pool (xSecureContexts). * * @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array. */ static void vReturnSecureContext( uint32_t ulSecureContextIndex ); /* These are implemented in assembly. */ extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ); extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ); /*-----------------------------------------------------------*/ static uint32_t ulGetSecureContext( void * pvTaskHandle ) { /* Start with invalid index. */ uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) && ( xSecureContexts[ i ].pucStackLimit == NULL ) && ( xSecureContexts[ i ].pucStackStart == NULL ) && ( xSecureContexts[ i ].pvTaskHandle == NULL ) && ( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = i; } else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle ) { /* A task can only have one secure context. Do not allocate a second * context for the same task. */ ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; break; } } return ulSecureContextIndex; } /*-----------------------------------------------------------*/ static void vReturnSecureContext( uint32_t ulSecureContextIndex ) { xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) { uint32_t ulIPSR, i; static uint32_t ulSecureContextsInitialized = 0; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) ) { /* Ensure to initialize secure contexts only once. */ ulSecureContextsInitialized = 1; /* No stack for thread mode until a task's context is loaded. */ secureportSET_PSPLIM( securecontextNO_STACK ); secureportSET_PSP( securecontextNO_STACK ); /* Initialize all secure contexts. */ for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { xSecureContexts[ i ].pucCurrentStackPointer = NULL; xSecureContexts[ i ].pucStackLimit = NULL; xSecureContexts[ i ].pucStackStart = NULL; xSecureContexts[ i ].pvTaskHandle = NULL; } #if ( configENABLE_MPU == 1 ) { /* Configure thread mode to use PSP and to be unprivileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED ); } #else /* configENABLE_MPU */ { /* Configure thread mode to use PSP and to be privileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED ); } #endif /* configENABLE_MPU */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ) #else /* configENABLE_MPU */ secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ) #endif /* configENABLE_MPU */ { uint8_t * pucStackMemory = NULL; uint8_t * pucStackLimit; uint32_t ulIPSR, ulSecureContextIndex; SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID; #if ( configENABLE_MPU == 1 ) uint32_t * pulCurrentStackPointer = NULL; #endif /* configENABLE_MPU */ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit * Register (PSPLIM) value. */ secureportREAD_IPSR( ulIPSR ); secureportREAD_PSPLIM( pucStackLimit ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. * Also do nothing, if a secure context us already loaded. PSPLIM is set to * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { /* Ontain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space. */ pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE ); if( pucStackMemory != NULL ) { /* Since stack grows down, the starting point will be the last * location. Note that this location is next to the last * allocated byte for stack (excluding the space for seal values) * because the hardware decrements the stack pointer before * writing i.e. if stack pointer is 0x2, a push operation will * decrement the stack pointer to 0x1 and then write at 0x1. */ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize; /* Seal the created secure process stack. */ *( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE; *( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE; /* The stack cannot go beyond this location. This value is * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle; #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 ) { *( 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 /* configENABLE_MPU */ { /* Current SP is set to the starting of the stack. This * value programmed in the PSP register on context switch. */ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart; } #endif /* configENABLE_MPU */ /* Ensure to never return 0 as a valid context handle. */ xSecureContextHandle = ulSecureContextIndex + 1UL; } } } return xSecureContextHandle; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint32_t ulIPSR, ulSecureContextIndex; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* Only free if a valid context handle is passed. */ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; /* Ensure that the secure context being deleted is associated with * the task. */ if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) { /* Free the stack space. */ vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); /* Return the secure context back to the free secure contexts pool. */ vReturnSecureContext( ulSecureContextIndex ); } } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that no secure context is loaded and the task is loading it's * own context. */ if( ( pucStackLimit == securecontextNO_STACK ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that task's context is loaded and the task is saving it's own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23/secure/secure_context.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_CONTEXT_H__ #define __SECURE_CONTEXT_H__ /* Standard includes. */ #include /* FreeRTOS includes. */ #include "FreeRTOSConfig.h" /** * @brief PSP value when no secure context is loaded. */ #define securecontextNO_STACK 0x0 /** * @brief Invalid context ID. */ #define securecontextINVALID_CONTEXT_ID 0UL /*-----------------------------------------------------------*/ /** * @brief Structure to represent a secure context. * * @note Since stack grows down, pucStackStart is the highest address while * pucStackLimit is the first address of the allocated memory. */ typedef struct SecureContext { uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */ uint8_t * pucStackStart; /**< First location of the stack memory. */ void * pvTaskHandle; /**< Task handle of the task this context is associated with. */ } SecureContext_t; /*-----------------------------------------------------------*/ /** * @brief Opaque handle for a secure context. */ typedef uint32_t SecureContextHandle_t; /*-----------------------------------------------------------*/ /** * @brief Initializes the secure context management system. * * PSP is set to NULL and therefore a task must allocate and load a context * before calling any secure side function in the thread mode. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureContext_Init( void ); /** * @brief Allocates a context on the secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] ulSecureStackSize Size of the stack to allocate on secure side. * @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise. * * @return Opaque context handle if context is successfully allocated, NULL * otherwise. */ #if ( configENABLE_MPU == 1 ) SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ); #else /* configENABLE_MPU */ SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ); #endif /* configENABLE_MPU */ /** * @brief Frees the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the * context to be freed. */ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Loads the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be loaded. */ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Saves the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be saved. */ void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); #endif /* __SECURE_CONTEXT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23/secure/secure_context_port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Secure context includes. */ #include "secure_context.h" /* Secure port macros. */ #include "secure_port_macros.h" #if ( configENABLE_FPU == 1 ) #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) { /* pxSecureContext value is in r0. */ __asm volatile ( " .syntax unified \n" " \n" " mrs r1, ipsr \n" /* r1 = IPSR. */ " cbz r1, load_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */ " ldmia r0!, {r1, r2} \n" /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */ " \n" #if ( configENABLE_MPU == 1 ) " ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */ " msr control, r3 \n" /* CONTROL = r3. */ #endif /* configENABLE_MPU */ " \n" " msr psplim, r2 \n" /* PSPLIM = r2. */ " msr psp, r1 \n" /* PSP = r1. */ " \n" " load_ctx_therad_mode: \n" " bx lr \n" " \n" ::: "r0", "r1", "r2" ); } /*-----------------------------------------------------------*/ void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) { /* pxSecureContext value is in r0. */ __asm volatile ( " .syntax unified \n" " \n" " mrs r1, ipsr \n" /* r1 = IPSR. */ " cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */ " mrs r1, psp \n" /* r1 = PSP. */ " \n" #if ( configENABLE_MPU == 1 ) " mrs r2, control \n" /* r2 = CONTROL. */ " subs r1, r1, #4 \n" /* Make space for the CONTROL value on the stack. */ " str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ " stmia r1!, {r2} \n" /* Store CONTROL value on the stack. */ #else /* configENABLE_MPU */ " str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ #endif /* configENABLE_MPU */ " \n" " movs r1, %0 \n" /* r1 = securecontextNO_STACK. */ " msr psplim, r1 \n" /* PSPLIM = securecontextNO_STACK. */ " msr psp, r1 \n" /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */ " \n" " save_ctx_therad_mode: \n" " bx lr \n" " \n" ::"i" ( securecontextNO_STACK ) : "r1", "memory" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23/secure/secure_heap.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure context heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Total heap size. */ #ifndef secureconfigTOTAL_HEAP_SIZE #define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) ) #endif /* No test marker by default. */ #ifndef mtCOVERAGE_TEST_MARKER #define mtCOVERAGE_TEST_MARKER() #endif /* No tracing by default. */ #ifndef traceMALLOC #define traceMALLOC( pvReturn, xWantedSize ) #endif /* No tracing by default. */ #ifndef traceFREE #define traceFREE( pv, xBlockSize ) #endif /* Block sizes must not get too small. */ #define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) /* Assumes 8bit bytes! */ #define secureheapBITS_PER_BYTE ( ( size_t ) 8 ) /*-----------------------------------------------------------*/ /* Allocate the memory for the heap. */ #if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) /* The application writer has already defined the array used for the RTOS * heap - probably so it can be placed in a special segment or address. */ extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #else /* configAPPLICATION_ALLOCATED_HEAP */ static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #endif /* configAPPLICATION_ALLOCATED_HEAP */ /** * @brief The linked list structure. * * This is used to link free blocks in order of their memory address. */ typedef struct A_BLOCK_LINK { struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */ size_t xBlockSize; /**< The size of the free block. */ } BlockLink_t; /*-----------------------------------------------------------*/ /** * @brief Called automatically to setup the required heap structures the first * time pvPortMalloc() is called. */ static void prvHeapInit( void ); /** * @brief Inserts a block of memory that is being freed into the correct * position in the list of free memory blocks. * * The block being freed will be merged with the block in front it and/or the * block behind it if the memory blocks are adjacent to each other. * * @param[in] pxBlockToInsert The block being freed. */ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ); /*-----------------------------------------------------------*/ /** * @brief The size of the structure placed at the beginning of each allocated * memory block must by correctly byte aligned. */ static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); /** * @brief Create a couple of list links to mark the start and end of the list. */ static BlockLink_t xStart; static BlockLink_t * pxEnd = NULL; /** * @brief Keeps track of the number of free bytes remaining, but says nothing * about fragmentation. */ static size_t xFreeBytesRemaining = 0U; static size_t xMinimumEverFreeBytesRemaining = 0U; /** * @brief Gets set to the top bit of an size_t type. * * When this bit in the xBlockSize member of an BlockLink_t structure is set * then the block belongs to the application. When the bit is free the block is * still part of the free heap space. */ static size_t xBlockAllocatedBit = 0; /*-----------------------------------------------------------*/ static void prvHeapInit( void ) { BlockLink_t * pxFirstFreeBlock; uint8_t * pucAlignedHeap; size_t uxAddress; size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE; /* Ensure the heap starts on a correctly aligned boundary. */ uxAddress = ( size_t ) ucHeap; if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 ) { uxAddress += ( secureportBYTE_ALIGNMENT - 1 ); uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; } pucAlignedHeap = ( uint8_t * ) uxAddress; /* xStart is used to hold a pointer to the first item in the list of free * blocks. The void cast is used to prevent compiler warnings. */ xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; xStart.xBlockSize = ( size_t ) 0; /* pxEnd is used to mark the end of the list of free blocks and is inserted * at the end of the heap space. */ uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; uxAddress -= xHeapStructSize; uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); pxEnd = ( void * ) uxAddress; pxEnd->xBlockSize = 0; pxEnd->pxNextFreeBlock = NULL; /* To start with there is a single free block that is sized to take up the * entire heap space, minus the space taken by pxEnd. */ pxFirstFreeBlock = ( void * ) pucAlignedHeap; pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; pxFirstFreeBlock->pxNextFreeBlock = pxEnd; /* Only one block exists - and it covers the entire usable heap space. */ xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; /* Work out the position of the top bit in a size_t variable. */ xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 ); } /*-----------------------------------------------------------*/ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) { BlockLink_t * pxIterator; uint8_t * puc; /* Iterate through the list until a block is found that has a higher address * than the block being inserted. */ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) { /* Nothing to do here, just iterate to the right position. */ } /* Do the block being inserted, and the block it is being inserted after * make a contiguous block of memory? */ puc = ( uint8_t * ) pxIterator; if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) { pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; pxBlockToInsert = pxIterator; } else { mtCOVERAGE_TEST_MARKER(); } /* Do the block being inserted, and the block it is being inserted before * make a contiguous block of memory? */ puc = ( uint8_t * ) pxBlockToInsert; if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) { if( pxIterator->pxNextFreeBlock != pxEnd ) { /* Form one big block from the two blocks. */ pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; } else { pxBlockToInsert->pxNextFreeBlock = pxEnd; } } else { pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } /* If the block being inserted plugged a gab, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ if( pxIterator != pxBlockToInsert ) { pxIterator->pxNextFreeBlock = pxBlockToInsert; } else { mtCOVERAGE_TEST_MARKER(); } } /*-----------------------------------------------------------*/ void * pvPortMalloc( size_t xWantedSize ) { BlockLink_t * pxBlock; BlockLink_t * pxPreviousBlock; BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ if( pxEnd == NULL ) { prvHeapInit(); } else { mtCOVERAGE_TEST_MARKER(); } /* Check the requested block size is not so large that the top bit is set. * The top bit of the block size member of the BlockLink_t structure is used * to determine who owns the block - the application or the kernel, so it * must be free. */ if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) { /* The wanted size is increased so it can contain a BlockLink_t * structure in addition to the requested amount of bytes. */ if( xWantedSize > 0 ) { xWantedSize += xHeapStructSize; /* Ensure that blocks are always aligned to the required number of * bytes. */ if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 ) { /* Byte alignment required. */ xWantedSize += ( secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) ); secureportASSERT( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) == 0 ); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) { /* Traverse the list from the start (lowest address) block until * one of adequate size is found. */ pxPreviousBlock = &xStart; pxBlock = xStart.pxNextFreeBlock; while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) { pxPreviousBlock = pxBlock; pxBlock = pxBlock->pxNextFreeBlock; } /* If the end marker was reached then a block of adequate size was * not found. */ if( pxBlock != pxEnd ) { /* Return the memory space pointed to - jumping over the * BlockLink_t structure at its start. */ pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); /* This block is being returned for use so must be taken out * of the list of free blocks. */ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; /* If the block is larger than required it can be split into * two. */ if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE ) { /* This block is to be split into two. Create a new * block following the number of bytes requested. The void * cast is used to prevent byte alignment warnings from the * compiler. */ pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 ); /* Calculate the sizes of two blocks split from the single * block. */ pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; pxBlock->xBlockSize = xWantedSize; /* Insert the new block into the list of free blocks. */ prvInsertBlockIntoFreeList( pxNewBlockLink ); } else { mtCOVERAGE_TEST_MARKER(); } xFreeBytesRemaining -= pxBlock->xBlockSize; if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) { xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; } else { mtCOVERAGE_TEST_MARKER(); } /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ pxBlock->xBlockSize |= xBlockAllocatedBit; pxBlock->pxNextFreeBlock = NULL; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } traceMALLOC( pvReturn, xWantedSize ); #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { extern void vApplicationMallocFailedHook( void ); vApplicationMallocFailedHook(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */ secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 ); return pvReturn; } /*-----------------------------------------------------------*/ void vPortFree( void * pv ) { uint8_t * puc = ( uint8_t * ) pv; BlockLink_t * pxLink; if( pv != NULL ) { /* The memory being freed will have an BlockLink_t structure immediately * before it. */ puc -= xHeapStructSize; /* This casting is to keep the compiler from issuing warnings. */ pxLink = ( void * ) puc; /* Check the block is actually allocated. */ secureportASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); secureportASSERT( pxLink->pxNextFreeBlock == NULL ); if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) { if( pxLink->pxNextFreeBlock == NULL ) { /* The block is being returned to the heap - it is no longer * allocated. */ pxLink->xBlockSize &= ~xBlockAllocatedBit; secureportDISABLE_NON_SECURE_INTERRUPTS(); { /* Add this block to the list of free blocks. */ xFreeBytesRemaining += pxLink->xBlockSize; traceFREE( pv, pxLink->xBlockSize ); prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); } secureportENABLE_NON_SECURE_INTERRUPTS(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } } /*-----------------------------------------------------------*/ size_t xPortGetFreeHeapSize( void ) { return xFreeBytesRemaining; } /*-----------------------------------------------------------*/ size_t xPortGetMinimumEverFreeHeapSize( void ) { return xMinimumEverFreeBytesRemaining; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23/secure/secure_heap.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_HEAP_H__ #define __SECURE_HEAP_H__ /* Standard includes. */ #include /** * @brief Allocates memory from heap. * * @param[in] xWantedSize The size of the memory to be allocated. * * @return Pointer to the memory region if the allocation is successful, NULL * otherwise. */ void * pvPortMalloc( size_t xWantedSize ); /** * @brief Frees the previously allocated memory. * * @param[in] pv Pointer to the memory to be freed. */ void vPortFree( void * pv ); /** * @brief Get the free heap size. * * @return Free heap size. */ size_t xPortGetFreeHeapSize( void ); /** * @brief Get the minimum ever free heap size. * * @return Minimum ever free heap size. */ size_t xPortGetMinimumEverFreeHeapSize( void ); #endif /* __SECURE_HEAP_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23/secure/secure_init.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure init includes. */ #include "secure_init.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Constants required to manipulate the SCB. */ #define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */ #define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL ) #define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS ) #define secureinitSCB_AIRCR_PRIS_POS ( 14UL ) #define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS ) /** * @brief Constants required to manipulate the FPU. */ #define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define secureinitFPCCR_LSPENS_POS ( 29UL ) #define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS ) #define secureinitFPCCR_TS_POS ( 26UL ) #define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS ) #define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */ #define secureinitNSACR_CP10_POS ( 10UL ) #define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS ) #define secureinitNSACR_CP11_POS ( 11UL ) #define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS ) /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { *( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) | ( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) | ( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK ); } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* CP10 = 1 ==> Non-secure access to the Floating Point Unit is * permitted. CP11 should be programmed to the same value as CP10. */ *( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK ); /* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures * that we can enable/disable lazy stacking in port.c file. */ *( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK ); /* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP * registers (S16-S31) are also pushed to stack on exception entry and * restored on exception return. */ *( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK ); } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23/secure/secure_init.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_INIT_H__ #define __SECURE_INIT_H__ /** * @brief De-prioritizes the non-secure exceptions. * * This is needed to ensure that the non-secure PendSV runs at the lowest * priority. Context switch is done in the non-secure PendSV handler. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_DePrioritizeNSExceptions( void ); /** * @brief Sets up the Floating Point Unit (FPU) for Non-Secure access. * * Also sets FPCCR.TS=1 to ensure that the content of the Floating Point * Registers are not leaked to the non-secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_EnableNSFPUAccess( void ); #endif /* __SECURE_INIT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23/secure/secure_port_macros.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_PORT_MACROS_H__ #define __SECURE_PORT_MACROS_H__ /** * @brief Byte alignment requirements. */ #define secureportBYTE_ALIGNMENT 8 #define secureportBYTE_ALIGNMENT_MASK ( 0x0007 ) /** * @brief Macro to declare a function as non-secure callable. */ #if defined( __IAR_SYSTEMS_ICC__ ) #define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root #else #define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) ) #endif /** * @brief Set the secure PRIMASK value. */ #define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Set the non-secure PRIMASK value. */ #define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Read the PSP value in the given variable. */ #define secureportREAD_PSP( pucOutCurrentStackPointer ) \ __asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) ) /** * @brief Set the PSP to the given value. */ #define secureportSET_PSP( pucCurrentStackPointer ) \ __asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) ) /** * @brief Read the PSPLIM value in the given variable. */ #define secureportREAD_PSPLIM( pucOutStackLimit ) \ __asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) ) /** * @brief Set the PSPLIM to the given value. */ #define secureportSET_PSPLIM( pucStackLimit ) \ __asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) ) /** * @brief Set the NonSecure MSP to the given value. */ #define secureportSET_MSP_NS( pucMainStackPointer ) \ __asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) ) /** * @brief Set the CONTROL register to the given value. */ #define secureportSET_CONTROL( ulControl ) \ __asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" ) /** * @brief Read the Interrupt Program Status Register (IPSR) value in the given * variable. */ #define secureportREAD_IPSR( ulIPSR ) \ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) ) /** * @brief PRIMASK value to enable interrupts. */ #define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0 /** * @brief PRIMASK value to disable interrupts. */ #define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1 /** * @brief Disable secure interrupts. */ #define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Disable non-secure interrupts. * * This effectively disables context switches. */ #define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Enable non-secure interrupts. */ #define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL ) /** * @brief Assert definition. */ #define secureportASSERT( x ) \ if( ( x ) == 0 ) \ { \ secureportDISABLE_SECURE_INTERRUPTS(); \ secureportDISABLE_NON_SECURE_INTERRUPTS(); \ for( ; ; ) {; } \ } #endif /* __SECURE_PORT_MACROS_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23_NTZ/non_secure/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /* Portasm includes. */ #include "portasm.h" #if ( configENABLE_TRUSTZONE == 1 ) /* Secure components includes. */ #include "secure_context.h" #include "secure_init.h" #endif /* configENABLE_TRUSTZONE */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /** * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS * on the secure side. The following are the valid configuration seetings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 * * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 * * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 */ #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. #endif /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the SCB. */ #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the FPU. */ #define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) #define portMPU_RLAR_REGION_ENABLE ( 1UL ) /* Enable privileged access to unmapped region. */ #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /*-----------------------------------------------------------*/ /** * @brief The maximum 24-bit number. * * It is needed because the systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /** * @brief A fiddle factor to estimate the number of SysTick counts that would * have occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) /** * @brief Initial EXC_RETURN value. * * FF FF FF FD * 1111 1111 1111 1111 1111 1111 1111 1101 * * Bit[6] - 1 --> The exception was taken from the Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 1 --> The exception was taken to the Secure state. */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else /** * @brief Initial EXC_RETURN value. * * FF FF FF BC * 1111 1111 1111 1111 1111 1111 1011 1100 * * Bit[6] - 0 --> The exception was taken from the Non-Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 0 --> The exception was taken to the Non-Secure state. */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ /** * @brief CONTROL register privileged bit mask. * * Bit[0] in CONTROL register tells the privilege: * Bit[0] = 0 ==> The task is privileged. * Bit[0] = 1 ==> The task is not privileged. */ #define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) /** * @brief Initial CONTROL register values. */ #define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) #define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) /** * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /** * @brief 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /** * @brief If portPRELOAD_REGISTERS then registers will be given an initial value * when a task is created. This helps in debugging at the cost of code size. */ #define portPRELOAD_REGISTERS 1 /** * @brief A task is created without a secure context, and must call * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes * any secure calls. */ #define portNO_SECURE_CONTEXT 0 /*-----------------------------------------------------------*/ /** * @brief Used to catch tasks that attempt to return from their implementing * function. */ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) /** * @brief Setup the Memory Protection Unit (MPU). */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) /** * @brief Setup the Floating Point Unit (FPU). */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ /** * @brief Setup the timer to generate the tick interrupts. * * The implementation in this file is weak to allow application writers to * change the timer used to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /** * @brief Checks whether the current execution context is interrupt. * * @return pdTRUE if the current execution context is interrupt, pdFALSE * otherwise. */ BaseType_t xPortIsInsideInterrupt( void ); /** * @brief Yield the processor. */ void vPortYield( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ void vPortExitCritical( void ) PRIVILEGED_FUNCTION; /** * @brief SysTick handler. */ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; /** * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. */ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Saved as part of the task context to indicate which context the * task is using on the secure side. */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ #if ( configUSE_TICKLESS_IDLE == 1 ) /** * @brief The number of SysTick increments that make up one tick period. */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; /** * @brief The maximum number of tick periods that can be suppressed is * limited by the 24 bit resolution of the SysTick timer. */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; /** * @brief Compensate for the CPU cycles that pass while the SysTick is * stopped (low power functionality only). */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). Artificially force an assert() * to be triggered if configASSERT() is defined, then stop here so * application writers can catch the error. */ configASSERT( ulCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being * defined but never called. ulDummy is used purely to quieten other * warnings about code appearing after this function is called - making * ulDummy volatile makes the compiler think the function could return * and therefore not output an 'unreachable code' warning for code that * appears after it. */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; extern uint32_t * __unprivileged_flash_start__; extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* if defined( __ARMCC_VERSION ) */ /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; extern uint32_t __unprivileged_flash_start__[]; extern uint32_t __unprivileged_flash_end__[]; extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check that the MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* MAIR0 - Index 0. */ portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); /* MAIR0 - Index 1. */ portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* Setup privileged flash as Read Only so that privileged tasks can * read it but not modify. */ portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged flash as Read Only by both privileged and * unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged syscalls flash as Read Only by both privileged * and unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup RAM containing kernel data for privileged access only. */ portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Enable mem fault. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; /* Enable MPU with privileged background access i.e. unmapped * regions have privileged access. */ portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) { /* Enable non-secure access to the FPU. */ SecureInit_EnableNSFPUAccess(); } #endif /* configENABLE_TRUSTZONE */ /* CP10 = 11 ==> Full access to FPU i.e. both privileged and * unprivileged code should be able to access FPU. CP11 should be * programmed to the same value as CP10. */ *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) ); /* ASPEN = 1 ==> Hardware should automatically preserve floating point * context on exception entry and restore on exception return. * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ void vPortYield( void ) /* PRIVILEGED_FUNCTION */ { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ { portDISABLE_INTERRUPTS(); ulCriticalNesting++; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ { configASSERT( ulCriticalNesting ); ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { #if ( configENABLE_MPU == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ #endif /* configENABLE_MPU */ uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) uint32_t ulR0, ulR1; extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ #endif /* configENABLE_TRUSTZONE */ uint8_t ucSVCNumber; /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ ulPC = pulCallerStackAddress[ 6 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { #if ( configENABLE_TRUSTZONE == 1 ) case portSVC_ALLOCATE_SECURE_CONTEXT: /* R0 contains the stack size passed as parameter to the * vPortAllocateSecureContext function. */ ulR0 = pulCallerStackAddress[ 0 ]; #if ( configENABLE_MPU == 1 ) { /* Read the CONTROL register value. */ __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); /* The task that raised the SVC is privileged if Bit[0] * in the CONTROL register is 0. */ ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: /* R0 contains TCB being freed and R1 contains the secure * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) { /* De-prioritize the non-secure exceptions so that the * non-secure pendSV runs at the lowest priority. */ SecureInit_DePrioritizeNSExceptions(); /* Initialize the secure context management system. */ SecureContext_Init(); } #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_FPU == 1 ) { /* Setup the Floating Point Unit (FPU). */ prvSetupFPU(); } #endif /* configENABLE_FPU */ /* Setup the context of the first task so that the first task starts * executing. */ vRestoreContextOfFirstTask(); break; #if ( configENABLE_MPU == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the svc was raised from any of * the system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { vRaisePrivilege(); } break; #endif /* configENABLE_MPU */ default: /* Incorrect SVC call. */ configASSERT( pdFALSE ); } } /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #if ( configENABLE_MPU == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /* *INDENT-ON* */ { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #endif /* portPRELOAD_REGISTERS */ return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ prvSetupMPU(); } #endif /* configENABLE_MPU */ /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; /* Start the first task. */ vStartFirstTask(); /* Should never get here as the tasks will now be executing. Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* Setup MAIR0. */ xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ if( ulStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged * SRAM is already protected using an MPU region and ARMv8-M does * not allow overlapping MPU regions. */ if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) { xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; } else { /* Define the region that allows access to the stack. */ ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); } } /* User supplied configurable regions. */ for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) { /* If xRegions is NULL i.e. the task has not specified any MPU * region, the else part ensures that all the configurable MPU * regions are invalidated. */ if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) { /* Translate the generic region definition contained in xRegions * into the ARMv8 specific MPU settings that are then stored in * xMPUSettings. */ ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; /* Start address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ); /* RO/RW. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); } else { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); } /* XN. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); } /* End Address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { /* Attr1 in MAIR0 is configured as device memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; } else { /* Attr0 in MAIR0 is configured as normal memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; } } else { /* Invalidate the region. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; } lIndex++; } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. Interrupt Program * Status Register (IPSR) holds the exception number of the currently-executing * exception or zero for Thread mode.*/ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION * is defined correctly and privileged functions are placed in correct sections. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Portasm includes. */ #include "portasm.h" /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #if ( configENABLE_FPU == 1 ) #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " movs r4, #1 \n"/* r4 = 1. */ " bics r3, r4 \n"/* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ " str r3, [r2] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r4, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " movs r4, #4 \n"/* r4 = 4. */ " str r4, [r2] \n"/* Program RNR = 4. */ " ldmia r1!, {r5,r6} \n"/* Read first set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r5,r6} \n"/* Write first set of RBAR/RLAR registers. */ " movs r4, #5 \n"/* r4 = 5. */ " str r4, [r2] \n"/* Program RNR = 5. */ " ldmia r1!, {r5,r6} \n"/* Read second set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r5,r6} \n"/* Write second set of RBAR/RLAR registers. */ " movs r4, #6 \n"/* r4 = 6. */ " str r4, [r2] \n"/* Program RNR = 6. */ " ldmia r1!, {r5,r6} \n"/* Read third set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r5,r6} \n"/* Write third set of RBAR/RLAR registers. */ " movs r4, #7 \n"/* r4 = 7. */ " str r4, [r2] \n"/* Program RNR = 7. */ " ldmia r1!, {r5,r6} \n"/* Read fourth set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r5,r6} \n"/* Write fourth set of RBAR/RLAR registers. */ " \n" " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " movs r4, #1 \n"/* r4 = 1. */ " orrs r3, r4 \n"/* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ " str r3, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ " msr control, r2 \n"/* Set this task's CONTROL value. */ " 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. */ " isb \n" " bx r3 \n"/* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ " movs r1, #2 \n"/* r1 = 2. */ " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ " 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. */ " isb \n" " bx r2 \n"/* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst2: .word 0xe000ed94 \n" "xMAIR0Const2: .word 0xe000edc0 \n" "xRNRConst2: .word 0xe000ed98 \n" "xRBARConst2: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " movs r1, #1 \n"/* r1 = 1. */ " 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. */ " movs r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ " bx lr \n"/* Return. */ " running_privileged: \n" " movs r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n"/* Return. */ " \n" " .align 4 \n" ::: "r0", "r1", "memory" ); } /*-----------------------------------------------------------*/ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* Read the CONTROL register. */ " movs r1, #1 \n"/* r1 = 1. */ " bics r0, r1 \n"/* Clear the bit 0. */ " msr control, r0 \n"/* Write back the new CONTROL value. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "r1", "memory" ); } /*-----------------------------------------------------------*/ void vResetPrivilege( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " movs r1, #1 \n"/* r1 = 1. */ " orrs r0, r1 \n"/* r0 = r0 | r1. */ " msr control, r0 \n"/* CONTROL = r0. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "r1", "memory" ); } /*-----------------------------------------------------------*/ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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"/* The first entry in vector table is stack pointer. */ " msr msp, r0 \n"/* Set the MSP back to the start of the stack. */ " cpsie i \n"/* Globally enable interrupts. */ " dsb \n" " isb \n" " svc %0 \n"/* System call to start the first task. */ " nop \n" " \n" " .align 4 \n" "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } /*-----------------------------------------------------------*/ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, PRIMASK \n" " cpsid i \n" " bx lr \n" ::: "memory" ); } /*-----------------------------------------------------------*/ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " msr PRIMASK, r0 \n" " bx lr \n" ::: "memory" ); } /*-----------------------------------------------------------*/ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, psp \n"/* Read PSP in r0. */ " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) " subs r0, r0, #44 \n"/* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */ " str r0, [r1] \n"/* Save the new top of stack in TCB. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r2, control \n"/* r2 = CONTROL. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " stmia r0!, {r1-r7} \n"/* Store on the stack - PSPLIM, CONTROL, LR and low registers that are not automatically saved. */ " mov r4, r8 \n"/* r4 = r8. */ " mov r5, r9 \n"/* r5 = r9. */ " mov r6, r10 \n"/* r6 = r10. */ " mov r7, r11 \n"/* r7 = r11. */ " stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ #else /* configENABLE_MPU */ " 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. */ " mrs r2, psplim \n"/* r2 = PSPLIM. */ " 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. */ " mov r4, r8 \n"/* r4 = r8. */ " mov r5, r9 \n"/* r5 = r9. */ " mov r6, r10 \n"/* r6 = r10. */ " mov r7, r11 \n"/* r7 = r11. */ " stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ #endif /* configENABLE_MPU */ " \n" " cpsid i \n" " bl vTaskSwitchContext \n" " cpsie i \n" " \n" " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " movs r4, #1 \n"/* r4 = 1. */ " bics r3, r4 \n"/* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ " str r3, [r2] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r4, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " movs r4, #4 \n"/* r4 = 4. */ " str r4, [r2] \n"/* Program RNR = 4. */ " ldmia r1!, {r5,r6} \n"/* Read first set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r5,r6} \n"/* Write first set of RBAR/RLAR registers. */ " movs r4, #5 \n"/* r4 = 5. */ " str r4, [r2] \n"/* Program RNR = 5. */ " ldmia r1!, {r5,r6} \n"/* Read second set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r5,r6} \n"/* Write second set of RBAR/RLAR registers. */ " movs r4, #6 \n"/* r4 = 6. */ " str r4, [r2] \n"/* Program RNR = 6. */ " ldmia r1!, {r5,r6} \n"/* Read third set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r5,r6} \n"/* Write third set of RBAR/RLAR registers. */ " movs r4, #7 \n"/* r4 = 7. */ " str r4, [r2] \n"/* Program RNR = 7. */ " ldmia r1!, {r5,r6} \n"/* Read fourth set of RBAR/RLAR from TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " stmia r3!, {r5,r6} \n"/* Write fourth set of RBAR/RLAR registers. */ " \n" " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " movs r4, #1 \n"/* r4 = 1. */ " orrs r3, r4 \n"/* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ " str r3, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " adds r0, r0, #28 \n"/* Move to the high registers. */ " ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ " mov r8, r4 \n"/* r8 = r4. */ " mov r9, r5 \n"/* r9 = r5. */ " mov r10, r6 \n"/* r10 = r6. */ " mov r11, r7 \n"/* r11 = r7. */ " msr psp, r0 \n"/* Remember the new top of stack for the task. */ " subs r0, r0, #44 \n"/* Move to the starting of the saved context. */ " ldmia r0!, {r1-r7} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */ " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ " msr control, r2 \n"/* Restore the CONTROL register value for the task. */ " bx r3 \n" #else /* configENABLE_MPU */ " adds r0, r0, #24 \n"/* Move to the high registers. */ " ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ " mov r8, r4 \n"/* r8 = r4. */ " mov r9, r5 \n"/* r9 = r5. */ " mov r10, r6 \n"/* r10 = r6. */ " mov r11, r7 \n"/* r11 = r7. */ " 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. */ " 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. */ " bx r3 \n" #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst: .word 0xe000ed94 \n" "xMAIR0Const: .word 0xe000edc0 \n" "xRNRConst: .word 0xe000ed98 \n" "xRBARConst: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } /*-----------------------------------------------------------*/ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " movs r0, #4 \n" " mov r1, lr \n" " tst r0, r1 \n" " beq stacking_used_msp \n" " mrs r0, psp \n" " ldr r2, svchandler_address_const \n" " bx r2 \n" " stacking_used_msp: \n" " mrs r0, msp \n" " ldr r2, svchandler_address_const \n" " bx r2 \n" " \n" " .align 4 \n" "svchandler_address_const: .word vPortSVCHandler_C \n" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORT_ASM_H__ #define __PORT_ASM_H__ /* Scheduler includes. */ #include "FreeRTOS.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /** * @brief Restore the context of the first task so that the first task starts * executing. */ void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * * @note This is a privileged function and should only be called from the kenrel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Starts the first task. */ void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Disables interrupts. */ uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Enables interrupts. */ void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief PendSV Exception handler. */ void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief SVC Handler. */ void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Allocate a Secure context for the calling task. * * @param[in] ulSecureStackSize The size of the stack to be allocated on the * secure side for the calling task. */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); /** * @brief Free the task's secure context. * * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. */ void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* __PORT_ASM_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M23" #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACROCOMMON_H #define PORTMACROCOMMON_H #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_FPU #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. #endif /* configENABLE_FPU */ #ifndef configENABLE_MPU #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. #endif /* configENABLE_MPU */ #ifndef configENABLE_TRUSTZONE #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ /** * @brief Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif #define portHAS_STACK_OVERFLOW_CHECKING 1 /*-----------------------------------------------------------*/ /** * @brief Extern declarations. */ extern BaseType_t xPortIsInsideInterrupt( void ); extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; #if ( configENABLE_TRUSTZONE == 1 ) extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_MPU == 1 ) extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief MPU specific constants. */ #if ( configENABLE_MPU == 1 ) #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #else #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* MPU regions. */ #define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_RAM_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ /* Device memory attributes used in MPU_MAIR registers. * * 8-bit values encoded as follows: * Bit[7:4] - 0000 - Device Memory * Bit[3:2] - 00 --> Device-nGnRnE * 01 --> Device-nGnRE * 10 --> Device-nGRE * 11 --> Device-GRE * Bit[1:0] - 00, Reserved. */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ /* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ /* Attributes used in MPU_RBAR registers. */ #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ /** * @brief Settings to define an MPU region. */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */ } MPURegionSettings_t; /** * @brief MPU settings as stored in the TCB. */ typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ } xMPU_SETTINGS; /*-----------------------------------------------------------*/ /** * @brief SVC numbers. */ #define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 /*-----------------------------------------------------------*/ /** * @brief Scheduler utilities. */ #define portYIELD() vPortYield() #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /** * @brief Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /** * @brief Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Allocate a secure context for the task. * * 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 context before it calls any secure function. * * @param[in] ulSecureStackSize The size of the secure stack to be allocated. */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) /** * @brief Called when a task is deleted to delete the task's secure context, * if it has one. * * @param[in] pxTCB The TCB of the task being deleted. */ #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. * * 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, * the privilege is not raised. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() #else #define portIS_PRIVILEGED() #define portRAISE_PRIVILEGE() #define portRESET_PRIVILEGE() #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief Barriers. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACROCOMMON_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM3/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM3 port. *----------------------------------------------------------*/ /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is * defined. The value should also ensure backward compatibility. * FreeRTOS.org versions prior to V4.4.0 did not include this definition. */ #ifndef configKERNEL_INTERRUPT_PRIORITY #define configKERNEL_INTERRUPT_PRIORITY 255 #endif /* Constants required to manipulate the core. Registers first... */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) /* ...then bits in the registers. */ #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) #define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) ) #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ #define portVECTACTIVE_MASK ( 0xFFUL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000UL ) /* The systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /* A fiddle factor to estimate the number of SysTick counts that would have * occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) /* Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /* 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 * debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ); /* * Exception handlers. */ void xPortPendSVHandler( void ) __attribute__( ( naked ) ); void xPortSysTickHandler( void ); void vPortSVCHandler( void ) __attribute__( ( naked ) ); /* * Start first task is a separate function so it can be tested in isolation. */ static void prvPortStartFirstTask( void ) __attribute__( ( naked ) ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* Each task maintains its own interrupt status in the critical nesting * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* * The number of SysTick increments that make up one tick period. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulTimerCountsForOneTick = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * The maximum number of tick periods that can be suppressed is limited by the * 24 bit resolution of the SysTick timer. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t xMaximumPossibleSuppressedTicks = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Compensate for the CPU cycles that pass while the SysTick is stopped (low * power functionality only. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. */ #if ( configASSERT_DEFINED == 1 ) static uint8_t ucMaxSysCallPriority = 0; static uint32_t ulMaxPRIGROUPValue = 0; static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). * * Artificially force an assert() to be triggered if configASSERT() is * defined, then stop here so application writers can catch the error. */ configASSERT( uxCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being defined * but never called. ulDummy is used purely to quieten other warnings * about code appearing after this function is called - making ulDummy * volatile makes the compiler think the function could return and * therefore not output an 'unreachable code' warning for code that appears * after it. */ } } /*-----------------------------------------------------------*/ void vPortSVCHandler( void ) { __asm volatile ( " ldr r3, pxCurrentTCBConst2 \n"/* Restore the context. */ " ldr r1, [r3] \n"/* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. */ " ldmia r0!, {r4-r11} \n"/* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ " msr psp, r0 \n"/* Restore the task stack pointer. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n" " orr r14, #0xd \n" " bx r14 \n" " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" ); } /*-----------------------------------------------------------*/ static void prvPortStartFirstTask( void ) { __asm volatile ( " ldr r0, =0xE000ED08 \n"/* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" " ldr r0, [r0] \n" " msr msp, r0 \n"/* Set the msp back to the start of the stack. */ " cpsie i \n"/* Globally enable interrupts. */ " cpsie f \n" " dsb \n" " isb \n" " svc 0 \n"/* System call to start first task. */ " nop \n" " .ltorg \n" ); } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API * functions can be called. ISR safe functions are those that end in * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { ulMaxPRIGROUPValue--; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); } #endif /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; /* Restore the clobbered interrupt priority register to its original * value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Start the first task. */ prvPortStartFirstTask(); /* Should never get here as the tasks will now be executing! Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimisation does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); uxCriticalNesting++; /* 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 * 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 * assert function also uses a critical section. */ if( uxCriticalNesting == 1 ) { configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void xPortPendSVHandler( void ) { /* This is a naked function. */ __asm volatile ( " mrs r0, psp \n" " isb \n" " \n" " ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */ " ldr r2, [r3] \n" " \n" " stmdb r0!, {r4-r11} \n"/* Save the remaining registers. */ " str r0, [r2] \n"/* Save the new top of stack into the first member of the TCB. */ " \n" " stmdb sp!, {r3, r14} \n" " mov r0, %0 \n" " msr basepri, r0 \n" " bl vTaskSwitchContext \n" " mov r0, #0 \n" " msr basepri, r0 \n" " ldmia sp!, {r3, r14} \n" " \n"/* Restore the context, including the critical nesting count. */ " ldr r1, [r3] \n" " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. */ " ldmia r0!, {r4-r11} \n"/* Pop the registers. */ " msr psp, r0 \n" " isb \n" " bx r14 \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { /* The SysTick runs at the lowest interrupt priority, so when this interrupt * executes all interrupts must be unmasked. There is therefore no need to * save and then restore the interrupt mask value as its value is already * known. */ portDISABLE_INTERRUPTS(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* A context switch is required. Context switching is performed in * the PendSV interrupt. Pend the PendSV interrupt. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portENABLE_INTERRUPTS(); } /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ /* * Setup the systick timer to generate the tick interrupts at the required * frequency. */ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and clear the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); } /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); /* Is the interrupt number a user defined interrupt? */ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /* Look up the interrupt's priority. */ ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Interrupts that use the FreeRTOS API must not be left at their * default priority of zero as that is the highest possible priority, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * and therefore also guaranteed to be invalid. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } /* Priority grouping: The interrupt controller (NVIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined * to be pre-emption priority bits. The following assertion will fail if * this is not the case (if some bits represent a sub-priority). * * If the application only uses CMSIS libraries for interrupt * configuration then the correct setting can be achieved on all Cortex-M * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * scheduler. Note however that some vendor specific peripheral libraries * assume a non-zero priority group setting, in which cases using a value * of zero will result in unpredictable behaviour. */ configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); } #endif /* configASSERT_DEFINED */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM3/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ #define portYIELD() \ { \ /* Set a PendSV to request a context switch. */ \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ \ /* Barriers are normally not required but do ensure the code is completely \ * within the specified behaviour for the architecture. */ \ __asm volatile ( "dsb" ::: "memory" ); \ __asm volatile ( "isb" ); \ } #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x ) #define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() #define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /* 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 * (which build with all the ports) will build. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Generic helper function. */ __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) { uint8_t ucReturn; __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" ); return ucReturn; } /* Check the configuration. */ #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. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /*-----------------------------------------------------------*/ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* portNOP() is not required by this port. */ #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif /*-----------------------------------------------------------*/ portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ portFORCE_INLINE static void vPortRaiseBASEPRI( void ) { uint32_t ulNewBASEPRI; __asm volatile ( " mov %0, %1 \n"\ " msr basepri, %0 \n"\ " isb \n"\ " dsb \n"\ : "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); } /*-----------------------------------------------------------*/ portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) { uint32_t ulOriginalBASEPRI, ulNewBASEPRI; __asm volatile ( " mrs %0, basepri \n"\ " mov %1, %2 \n"\ " msr basepri, %1 \n"\ " isb \n"\ " dsb \n"\ : "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); /* This return will not be reached but is necessary to prevent compiler * warnings. */ return ulOriginalBASEPRI; } /*-----------------------------------------------------------*/ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) { __asm volatile ( " msr basepri, %0 "::"r" ( ulNewMaskValue ) : "memory" ); } /*-----------------------------------------------------------*/ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33/non_secure/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /* Portasm includes. */ #include "portasm.h" #if ( configENABLE_TRUSTZONE == 1 ) /* Secure components includes. */ #include "secure_context.h" #include "secure_init.h" #endif /* configENABLE_TRUSTZONE */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /** * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS * on the secure side. The following are the valid configuration seetings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 * * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 * * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 */ #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. #endif /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the SCB. */ #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the FPU. */ #define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) #define portMPU_RLAR_REGION_ENABLE ( 1UL ) /* Enable privileged access to unmapped region. */ #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /*-----------------------------------------------------------*/ /** * @brief The maximum 24-bit number. * * It is needed because the systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /** * @brief A fiddle factor to estimate the number of SysTick counts that would * have occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) /** * @brief Initial EXC_RETURN value. * * FF FF FF FD * 1111 1111 1111 1111 1111 1111 1111 1101 * * Bit[6] - 1 --> The exception was taken from the Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 1 --> The exception was taken to the Secure state. */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else /** * @brief Initial EXC_RETURN value. * * FF FF FF BC * 1111 1111 1111 1111 1111 1111 1011 1100 * * Bit[6] - 0 --> The exception was taken from the Non-Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 0 --> The exception was taken to the Non-Secure state. */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ /** * @brief CONTROL register privileged bit mask. * * Bit[0] in CONTROL register tells the privilege: * Bit[0] = 0 ==> The task is privileged. * Bit[0] = 1 ==> The task is not privileged. */ #define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) /** * @brief Initial CONTROL register values. */ #define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) #define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) /** * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /** * @brief 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /** * @brief If portPRELOAD_REGISTERS then registers will be given an initial value * when a task is created. This helps in debugging at the cost of code size. */ #define portPRELOAD_REGISTERS 1 /** * @brief A task is created without a secure context, and must call * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes * any secure calls. */ #define portNO_SECURE_CONTEXT 0 /*-----------------------------------------------------------*/ /** * @brief Used to catch tasks that attempt to return from their implementing * function. */ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) /** * @brief Setup the Memory Protection Unit (MPU). */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) /** * @brief Setup the Floating Point Unit (FPU). */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ /** * @brief Setup the timer to generate the tick interrupts. * * The implementation in this file is weak to allow application writers to * change the timer used to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /** * @brief Checks whether the current execution context is interrupt. * * @return pdTRUE if the current execution context is interrupt, pdFALSE * otherwise. */ BaseType_t xPortIsInsideInterrupt( void ); /** * @brief Yield the processor. */ void vPortYield( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ void vPortExitCritical( void ) PRIVILEGED_FUNCTION; /** * @brief SysTick handler. */ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; /** * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. */ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Saved as part of the task context to indicate which context the * task is using on the secure side. */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ #if ( configUSE_TICKLESS_IDLE == 1 ) /** * @brief The number of SysTick increments that make up one tick period. */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; /** * @brief The maximum number of tick periods that can be suppressed is * limited by the 24 bit resolution of the SysTick timer. */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; /** * @brief Compensate for the CPU cycles that pass while the SysTick is * stopped (low power functionality only). */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). Artificially force an assert() * to be triggered if configASSERT() is defined, then stop here so * application writers can catch the error. */ configASSERT( ulCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being * defined but never called. ulDummy is used purely to quieten other * warnings about code appearing after this function is called - making * ulDummy volatile makes the compiler think the function could return * and therefore not output an 'unreachable code' warning for code that * appears after it. */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; extern uint32_t * __unprivileged_flash_start__; extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* if defined( __ARMCC_VERSION ) */ /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; extern uint32_t __unprivileged_flash_start__[]; extern uint32_t __unprivileged_flash_end__[]; extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check that the MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* MAIR0 - Index 0. */ portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); /* MAIR0 - Index 1. */ portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* Setup privileged flash as Read Only so that privileged tasks can * read it but not modify. */ portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged flash as Read Only by both privileged and * unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged syscalls flash as Read Only by both privileged * and unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup RAM containing kernel data for privileged access only. */ portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Enable mem fault. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; /* Enable MPU with privileged background access i.e. unmapped * regions have privileged access. */ portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) { /* Enable non-secure access to the FPU. */ SecureInit_EnableNSFPUAccess(); } #endif /* configENABLE_TRUSTZONE */ /* CP10 = 11 ==> Full access to FPU i.e. both privileged and * unprivileged code should be able to access FPU. CP11 should be * programmed to the same value as CP10. */ *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) ); /* ASPEN = 1 ==> Hardware should automatically preserve floating point * context on exception entry and restore on exception return. * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ void vPortYield( void ) /* PRIVILEGED_FUNCTION */ { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ { portDISABLE_INTERRUPTS(); ulCriticalNesting++; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ { configASSERT( ulCriticalNesting ); ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { #if ( configENABLE_MPU == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ #endif /* configENABLE_MPU */ uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) uint32_t ulR0, ulR1; extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ #endif /* configENABLE_TRUSTZONE */ uint8_t ucSVCNumber; /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ ulPC = pulCallerStackAddress[ 6 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { #if ( configENABLE_TRUSTZONE == 1 ) case portSVC_ALLOCATE_SECURE_CONTEXT: /* R0 contains the stack size passed as parameter to the * vPortAllocateSecureContext function. */ ulR0 = pulCallerStackAddress[ 0 ]; #if ( configENABLE_MPU == 1 ) { /* Read the CONTROL register value. */ __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); /* The task that raised the SVC is privileged if Bit[0] * in the CONTROL register is 0. */ ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: /* R0 contains TCB being freed and R1 contains the secure * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) { /* De-prioritize the non-secure exceptions so that the * non-secure pendSV runs at the lowest priority. */ SecureInit_DePrioritizeNSExceptions(); /* Initialize the secure context management system. */ SecureContext_Init(); } #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_FPU == 1 ) { /* Setup the Floating Point Unit (FPU). */ prvSetupFPU(); } #endif /* configENABLE_FPU */ /* Setup the context of the first task so that the first task starts * executing. */ vRestoreContextOfFirstTask(); break; #if ( configENABLE_MPU == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the svc was raised from any of * the system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { vRaisePrivilege(); } break; #endif /* configENABLE_MPU */ default: /* Incorrect SVC call. */ configASSERT( pdFALSE ); } } /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #if ( configENABLE_MPU == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /* *INDENT-ON* */ { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #endif /* portPRELOAD_REGISTERS */ return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ prvSetupMPU(); } #endif /* configENABLE_MPU */ /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; /* Start the first task. */ vStartFirstTask(); /* Should never get here as the tasks will now be executing. Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* Setup MAIR0. */ xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ if( ulStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged * SRAM is already protected using an MPU region and ARMv8-M does * not allow overlapping MPU regions. */ if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) { xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; } else { /* Define the region that allows access to the stack. */ ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); } } /* User supplied configurable regions. */ for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) { /* If xRegions is NULL i.e. the task has not specified any MPU * region, the else part ensures that all the configurable MPU * regions are invalidated. */ if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) { /* Translate the generic region definition contained in xRegions * into the ARMv8 specific MPU settings that are then stored in * xMPUSettings. */ ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; /* Start address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ); /* RO/RW. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); } else { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); } /* XN. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); } /* End Address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { /* Attr1 in MAIR0 is configured as device memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; } else { /* Attr0 in MAIR0 is configured as normal memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; } } else { /* Invalidate the region. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; } lIndex++; } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. Interrupt Program * Status Register (IPSR) holds the exception number of the currently-executing * exception or zero for Thread mode.*/ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33/non_secure/portasm.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION * is defined correctly and privileged functions are placed in correct sections. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Portasm includes. */ #include "portasm.h" /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r4, [r2] \n"/* Disable MPU. */ " \n" " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r4, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r4, #4 \n"/* r4 = 4. */ " str r4, [r2] \n"/* Program RNR = 4. */ " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r3!, {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. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r4, #8 \n"/* r4 = 8. */ " str r4, [r2] \n"/* Program RNR = 8. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r3!, {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. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r4, #12 \n"/* r4 = 12. */ " str r4, [r2] \n"/* Program RNR = 12. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r3!, {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. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " str r4, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ " ldr r5, xSecureContextConst2 \n" " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ " msr control, r3 \n"/* Set this task's CONTROL value. */ " 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. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " bx r4 \n"/* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, xSecureContextConst2 \n" " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ " movs r1, #2 \n"/* r1 = 2. */ " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ " 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. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " bx r3 \n"/* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" "xSecureContextConst2: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst2: .word 0xe000ed94 \n" "xMAIR0Const2: .word 0xe000edc0 \n" "xRNRConst2: .word 0xe000ed98 \n" "xRBARConst2: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ " ite ne \n" " 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. */ " bx lr \n"/* Return. */ " \n" " .align 4 \n" ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* Read the CONTROL register. */ " bic r0, #1 \n"/* Clear the bit 0. */ " msr control, r0 \n"/* Write back the new CONTROL value. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vResetPrivilege( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " orr r0, #1 \n"/* r0 = r0 | 1. */ " msr control, r0 \n"/* CONTROL = r0. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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"/* The first entry in vector table is stack pointer. */ " msr msp, r0 \n"/* Set the MSP back to the start of the stack. */ " cpsie i \n"/* Globally enable interrupts. */ " cpsie f \n" " dsb \n" " isb \n" " svc %0 \n"/* System call to start the first task. */ " nop \n" " \n" " .align 4 \n" "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } /*-----------------------------------------------------------*/ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n"/* Return. */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); } /*-----------------------------------------------------------*/ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " msr basepri, r0 \n"/* basepri = ulMask. */ " dsb \n" " isb \n" " bx lr \n"/* Return. */ ::: "memory" ); } /*-----------------------------------------------------------*/ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" " 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 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. */ " mrs r2, psp \n"/* Read PSP in r2. */ " \n" " cbz r0, save_ns_context \n"/* No secure context to save. */ " push {r0-r2, r14} \n" " bl SecureContext_SaveContext \n"/* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r0-r3} \n"/* LR is now in 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. */ " 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" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB.*/ #if ( configENABLE_MPU == 1 ) " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ " str r2, [r1] \n"/* Save the new top of stack in TCB. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r3, control \n"/* r3 = CONTROL. */ " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ " 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. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ " b select_next_task \n" " \n" " save_ns_context: \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ #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. */ " it eq \n" " vstmdbeq r2!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ " str r2, [r1] \n"/* Save the new top of stack in TCB. */ " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r3, control \n"/* r3 = CONTROL. */ " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ " subs r2, r2, #16 \n"/* r2 = r2 - 16. */ " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ " 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. */ " adds r2, r2, #12 \n"/* r2 = r2 + 12. */ " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " subs r2, r2, #12 \n"/* r2 = r2 - 12. */ " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ " \n" " select_next_task: \n" " mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" " mov r0, #0 \n"/* r0 = 0. */ " msr basepri, r0 \n"/* Enable interrupts. */ " \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r4, [r3] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ " str r4, [r3] \n"/* Program MAIR0. */ " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ " movs r4, #4 \n"/* r4 = 4. */ " str r4, [r3] \n"/* Program RNR = 4. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ " movs r4, #8 \n"/* r4 = 8. */ " str r4, [r3] \n"/* Program RNR = 8. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ " movs r4, #12 \n"/* r4 = 12. */ " str r4, [r3] \n"/* Program RNR = 12. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " str r4, [r3] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ " mov lr, r4 \n"/* LR = r4. */ " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( 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. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " push {r2, r4} \n" " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r2, r4} \n" " 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. */ " 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. */ " bx lr \n" #else /* configENABLE_MPU */ " 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. */ " mov lr, r4 \n"/* LR = r4. */ " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( 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. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " push {r2, r4} \n" " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r2, r4} \n" " 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. */ " 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. */ " bx lr \n" #endif /* configENABLE_MPU */ " \n" " restore_ns_context: \n" " ldmia r2!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */ #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. */ " it eq \n" " vldmiaeq r2!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ " msr psp, r2 \n"/* Remember the new top of stack for the task. */ " bx lr \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" "xSecureContextConst: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst: .word 0xe000ed94 \n" "xMAIR0Const: .word 0xe000edc0 \n" "xRNRConst: .word 0xe000ed98 \n" "xRBARConst: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } /*-----------------------------------------------------------*/ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " tst lr, #4 \n" " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" " ldr r1, svchandler_address_const \n" " bx r1 \n" " \n" " .align 4 \n" "svchandler_address_const: .word vPortSVCHandler_C \n" ); } /*-----------------------------------------------------------*/ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " svc %0 \n"/* Secure context is allocated in the supervisor call. */ " bx lr \n"/* Return. */ ::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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. */ " cmp r1, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */ " it ne \n" " svcne %0 \n"/* Secure context is freed in the supervisor call. */ " bx lr \n"/* Return. */ ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33/non_secure/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORT_ASM_H__ #define __PORT_ASM_H__ /* Scheduler includes. */ #include "FreeRTOS.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /** * @brief Restore the context of the first task so that the first task starts * executing. */ void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * * @note This is a privileged function and should only be called from the kenrel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Starts the first task. */ void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Disables interrupts. */ uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Enables interrupts. */ void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief PendSV Exception handler. */ void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief SVC Handler. */ void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Allocate a Secure context for the calling task. * * @param[in] ulSecureStackSize The size of the stack to be allocated on the * secure side for the calling task. */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); /** * @brief Free the task's secure context. * * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. */ void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* __PORT_ASM_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33/non_secure/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M33" #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACROCOMMON_H #define PORTMACROCOMMON_H #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_FPU #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. #endif /* configENABLE_FPU */ #ifndef configENABLE_MPU #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. #endif /* configENABLE_MPU */ #ifndef configENABLE_TRUSTZONE #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ /** * @brief Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif #define portHAS_STACK_OVERFLOW_CHECKING 1 /*-----------------------------------------------------------*/ /** * @brief Extern declarations. */ extern BaseType_t xPortIsInsideInterrupt( void ); extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; #if ( configENABLE_TRUSTZONE == 1 ) extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_MPU == 1 ) extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief MPU specific constants. */ #if ( configENABLE_MPU == 1 ) #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #else #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* MPU regions. */ #define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_RAM_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ /* Device memory attributes used in MPU_MAIR registers. * * 8-bit values encoded as follows: * Bit[7:4] - 0000 - Device Memory * Bit[3:2] - 00 --> Device-nGnRnE * 01 --> Device-nGnRE * 10 --> Device-nGRE * 11 --> Device-GRE * Bit[1:0] - 00, Reserved. */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ /* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ /* Attributes used in MPU_RBAR registers. */ #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ /** * @brief Settings to define an MPU region. */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */ } MPURegionSettings_t; /** * @brief MPU settings as stored in the TCB. */ typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ } xMPU_SETTINGS; /*-----------------------------------------------------------*/ /** * @brief SVC numbers. */ #define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 /*-----------------------------------------------------------*/ /** * @brief Scheduler utilities. */ #define portYIELD() vPortYield() #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /** * @brief Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /** * @brief Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Allocate a secure context for the task. * * 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 context before it calls any secure function. * * @param[in] ulSecureStackSize The size of the secure stack to be allocated. */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) /** * @brief Called when a task is deleted to delete the task's secure context, * if it has one. * * @param[in] pxTCB The TCB of the task being deleted. */ #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. * * 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, * the privilege is not raised. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() #else #define portIS_PRIVILEGED() #define portRAISE_PRIVILEGE() #define portRESET_PRIVILEGE() #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief Barriers. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACROCOMMON_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33/secure/secure_context.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Secure context includes. */ #include "secure_context.h" /* Secure heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief CONTROL value for privileged tasks. * * Bit[0] - 0 --> Thread mode is privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_PRIVILEGED 0x02 /** * @brief CONTROL value for un-privileged tasks. * * Bit[0] - 1 --> Thread mode is un-privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 /** * @brief Size of stack seal values in bytes. */ #define securecontextSTACK_SEAL_SIZE 8 /** * @brief Stack seal value as recommended by ARM. */ #define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5 /** * @brief Maximum number of secure contexts. */ #ifndef secureconfigMAX_SECURE_CONTEXTS #define secureconfigMAX_SECURE_CONTEXTS 8UL #endif /*-----------------------------------------------------------*/ /** * @brief Pre-allocated array of secure contexts. */ SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ]; /*-----------------------------------------------------------*/ /** * @brief Get a free secure context for a task from the secure context pool (xSecureContexts). * * This function ensures that only one secure context is allocated for a task. * * @param[in] pvTaskHandle The task handle for which the secure context is allocated. * * @return Index of a free secure context in the xSecureContexts array. */ static uint32_t ulGetSecureContext( void * pvTaskHandle ); /** * @brief Return the secure context to the secure context pool (xSecureContexts). * * @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array. */ static void vReturnSecureContext( uint32_t ulSecureContextIndex ); /* These are implemented in assembly. */ extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ); extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ); /*-----------------------------------------------------------*/ static uint32_t ulGetSecureContext( void * pvTaskHandle ) { /* Start with invalid index. */ uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) && ( xSecureContexts[ i ].pucStackLimit == NULL ) && ( xSecureContexts[ i ].pucStackStart == NULL ) && ( xSecureContexts[ i ].pvTaskHandle == NULL ) && ( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = i; } else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle ) { /* A task can only have one secure context. Do not allocate a second * context for the same task. */ ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; break; } } return ulSecureContextIndex; } /*-----------------------------------------------------------*/ static void vReturnSecureContext( uint32_t ulSecureContextIndex ) { xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) { uint32_t ulIPSR, i; static uint32_t ulSecureContextsInitialized = 0; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) ) { /* Ensure to initialize secure contexts only once. */ ulSecureContextsInitialized = 1; /* No stack for thread mode until a task's context is loaded. */ secureportSET_PSPLIM( securecontextNO_STACK ); secureportSET_PSP( securecontextNO_STACK ); /* Initialize all secure contexts. */ for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { xSecureContexts[ i ].pucCurrentStackPointer = NULL; xSecureContexts[ i ].pucStackLimit = NULL; xSecureContexts[ i ].pucStackStart = NULL; xSecureContexts[ i ].pvTaskHandle = NULL; } #if ( configENABLE_MPU == 1 ) { /* Configure thread mode to use PSP and to be unprivileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED ); } #else /* configENABLE_MPU */ { /* Configure thread mode to use PSP and to be privileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED ); } #endif /* configENABLE_MPU */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ) #else /* configENABLE_MPU */ secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ) #endif /* configENABLE_MPU */ { uint8_t * pucStackMemory = NULL; uint8_t * pucStackLimit; uint32_t ulIPSR, ulSecureContextIndex; SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID; #if ( configENABLE_MPU == 1 ) uint32_t * pulCurrentStackPointer = NULL; #endif /* configENABLE_MPU */ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit * Register (PSPLIM) value. */ secureportREAD_IPSR( ulIPSR ); secureportREAD_PSPLIM( pucStackLimit ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. * Also do nothing, if a secure context us already loaded. PSPLIM is set to * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { /* Ontain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space. */ pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE ); if( pucStackMemory != NULL ) { /* Since stack grows down, the starting point will be the last * location. Note that this location is next to the last * allocated byte for stack (excluding the space for seal values) * because the hardware decrements the stack pointer before * writing i.e. if stack pointer is 0x2, a push operation will * decrement the stack pointer to 0x1 and then write at 0x1. */ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize; /* Seal the created secure process stack. */ *( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE; *( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE; /* The stack cannot go beyond this location. This value is * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle; #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 ) { *( 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 /* configENABLE_MPU */ { /* Current SP is set to the starting of the stack. This * value programmed in the PSP register on context switch. */ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart; } #endif /* configENABLE_MPU */ /* Ensure to never return 0 as a valid context handle. */ xSecureContextHandle = ulSecureContextIndex + 1UL; } } } return xSecureContextHandle; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint32_t ulIPSR, ulSecureContextIndex; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* Only free if a valid context handle is passed. */ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; /* Ensure that the secure context being deleted is associated with * the task. */ if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) { /* Free the stack space. */ vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); /* Return the secure context back to the free secure contexts pool. */ vReturnSecureContext( ulSecureContextIndex ); } } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that no secure context is loaded and the task is loading it's * own context. */ if( ( pucStackLimit == securecontextNO_STACK ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that task's context is loaded and the task is saving it's own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33/secure/secure_context.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_CONTEXT_H__ #define __SECURE_CONTEXT_H__ /* Standard includes. */ #include /* FreeRTOS includes. */ #include "FreeRTOSConfig.h" /** * @brief PSP value when no secure context is loaded. */ #define securecontextNO_STACK 0x0 /** * @brief Invalid context ID. */ #define securecontextINVALID_CONTEXT_ID 0UL /*-----------------------------------------------------------*/ /** * @brief Structure to represent a secure context. * * @note Since stack grows down, pucStackStart is the highest address while * pucStackLimit is the first address of the allocated memory. */ typedef struct SecureContext { uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */ uint8_t * pucStackStart; /**< First location of the stack memory. */ void * pvTaskHandle; /**< Task handle of the task this context is associated with. */ } SecureContext_t; /*-----------------------------------------------------------*/ /** * @brief Opaque handle for a secure context. */ typedef uint32_t SecureContextHandle_t; /*-----------------------------------------------------------*/ /** * @brief Initializes the secure context management system. * * PSP is set to NULL and therefore a task must allocate and load a context * before calling any secure side function in the thread mode. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureContext_Init( void ); /** * @brief Allocates a context on the secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] ulSecureStackSize Size of the stack to allocate on secure side. * @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise. * * @return Opaque context handle if context is successfully allocated, NULL * otherwise. */ #if ( configENABLE_MPU == 1 ) SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ); #else /* configENABLE_MPU */ SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ); #endif /* configENABLE_MPU */ /** * @brief Frees the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the * context to be freed. */ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Loads the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be loaded. */ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Saves the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be saved. */ void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); #endif /* __SECURE_CONTEXT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33/secure/secure_context_port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Secure context includes. */ #include "secure_context.h" /* Secure port macros. */ #include "secure_port_macros.h" void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) { /* pxSecureContext value is in r0. */ __asm volatile ( " .syntax unified \n" " \n" " mrs r1, ipsr \n" /* r1 = IPSR. */ " cbz r1, load_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */ " ldmia r0!, {r1, r2} \n" /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */ " \n" #if ( configENABLE_MPU == 1 ) " ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */ " msr control, r3 \n" /* CONTROL = r3. */ #endif /* configENABLE_MPU */ " \n" " msr psplim, r2 \n" /* PSPLIM = r2. */ " msr psp, r1 \n" /* PSP = r1. */ " \n" " load_ctx_therad_mode: \n" " bx lr \n" " \n" ::: "r0", "r1", "r2" ); } /*-----------------------------------------------------------*/ void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) { /* pxSecureContext value is in r0. */ __asm volatile ( " .syntax unified \n" " \n" " mrs r1, ipsr \n" /* r1 = IPSR. */ " cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */ " mrs r1, psp \n" /* r1 = PSP. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " vstmdb r1!, {s0} \n" /* Trigger the deferred stacking of FPU registers. */ " vldmia r1!, {s0} \n" /* Nullify the effect of the previous statement. */ #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" #if ( configENABLE_MPU == 1 ) " mrs r2, control \n" /* r2 = CONTROL. */ " stmdb r1!, {r2} \n" /* Store CONTROL value on the stack. */ #endif /* configENABLE_MPU */ " \n" " str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ " movs r1, %0 \n" /* r1 = securecontextNO_STACK. */ " msr psplim, r1 \n" /* PSPLIM = securecontextNO_STACK. */ " msr psp, r1 \n" /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */ " \n" " save_ctx_therad_mode: \n" " bx lr \n" " \n" ::"i" ( securecontextNO_STACK ) : "r1", "memory" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33/secure/secure_heap.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure context heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Total heap size. */ #ifndef secureconfigTOTAL_HEAP_SIZE #define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) ) #endif /* No test marker by default. */ #ifndef mtCOVERAGE_TEST_MARKER #define mtCOVERAGE_TEST_MARKER() #endif /* No tracing by default. */ #ifndef traceMALLOC #define traceMALLOC( pvReturn, xWantedSize ) #endif /* No tracing by default. */ #ifndef traceFREE #define traceFREE( pv, xBlockSize ) #endif /* Block sizes must not get too small. */ #define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) /* Assumes 8bit bytes! */ #define secureheapBITS_PER_BYTE ( ( size_t ) 8 ) /*-----------------------------------------------------------*/ /* Allocate the memory for the heap. */ #if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) /* The application writer has already defined the array used for the RTOS * heap - probably so it can be placed in a special segment or address. */ extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #else /* configAPPLICATION_ALLOCATED_HEAP */ static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #endif /* configAPPLICATION_ALLOCATED_HEAP */ /** * @brief The linked list structure. * * This is used to link free blocks in order of their memory address. */ typedef struct A_BLOCK_LINK { struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */ size_t xBlockSize; /**< The size of the free block. */ } BlockLink_t; /*-----------------------------------------------------------*/ /** * @brief Called automatically to setup the required heap structures the first * time pvPortMalloc() is called. */ static void prvHeapInit( void ); /** * @brief Inserts a block of memory that is being freed into the correct * position in the list of free memory blocks. * * The block being freed will be merged with the block in front it and/or the * block behind it if the memory blocks are adjacent to each other. * * @param[in] pxBlockToInsert The block being freed. */ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ); /*-----------------------------------------------------------*/ /** * @brief The size of the structure placed at the beginning of each allocated * memory block must by correctly byte aligned. */ static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); /** * @brief Create a couple of list links to mark the start and end of the list. */ static BlockLink_t xStart; static BlockLink_t * pxEnd = NULL; /** * @brief Keeps track of the number of free bytes remaining, but says nothing * about fragmentation. */ static size_t xFreeBytesRemaining = 0U; static size_t xMinimumEverFreeBytesRemaining = 0U; /** * @brief Gets set to the top bit of an size_t type. * * When this bit in the xBlockSize member of an BlockLink_t structure is set * then the block belongs to the application. When the bit is free the block is * still part of the free heap space. */ static size_t xBlockAllocatedBit = 0; /*-----------------------------------------------------------*/ static void prvHeapInit( void ) { BlockLink_t * pxFirstFreeBlock; uint8_t * pucAlignedHeap; size_t uxAddress; size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE; /* Ensure the heap starts on a correctly aligned boundary. */ uxAddress = ( size_t ) ucHeap; if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 ) { uxAddress += ( secureportBYTE_ALIGNMENT - 1 ); uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; } pucAlignedHeap = ( uint8_t * ) uxAddress; /* xStart is used to hold a pointer to the first item in the list of free * blocks. The void cast is used to prevent compiler warnings. */ xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; xStart.xBlockSize = ( size_t ) 0; /* pxEnd is used to mark the end of the list of free blocks and is inserted * at the end of the heap space. */ uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; uxAddress -= xHeapStructSize; uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); pxEnd = ( void * ) uxAddress; pxEnd->xBlockSize = 0; pxEnd->pxNextFreeBlock = NULL; /* To start with there is a single free block that is sized to take up the * entire heap space, minus the space taken by pxEnd. */ pxFirstFreeBlock = ( void * ) pucAlignedHeap; pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; pxFirstFreeBlock->pxNextFreeBlock = pxEnd; /* Only one block exists - and it covers the entire usable heap space. */ xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; /* Work out the position of the top bit in a size_t variable. */ xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 ); } /*-----------------------------------------------------------*/ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) { BlockLink_t * pxIterator; uint8_t * puc; /* Iterate through the list until a block is found that has a higher address * than the block being inserted. */ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) { /* Nothing to do here, just iterate to the right position. */ } /* Do the block being inserted, and the block it is being inserted after * make a contiguous block of memory? */ puc = ( uint8_t * ) pxIterator; if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) { pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; pxBlockToInsert = pxIterator; } else { mtCOVERAGE_TEST_MARKER(); } /* Do the block being inserted, and the block it is being inserted before * make a contiguous block of memory? */ puc = ( uint8_t * ) pxBlockToInsert; if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) { if( pxIterator->pxNextFreeBlock != pxEnd ) { /* Form one big block from the two blocks. */ pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; } else { pxBlockToInsert->pxNextFreeBlock = pxEnd; } } else { pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } /* If the block being inserted plugged a gab, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ if( pxIterator != pxBlockToInsert ) { pxIterator->pxNextFreeBlock = pxBlockToInsert; } else { mtCOVERAGE_TEST_MARKER(); } } /*-----------------------------------------------------------*/ void * pvPortMalloc( size_t xWantedSize ) { BlockLink_t * pxBlock; BlockLink_t * pxPreviousBlock; BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ if( pxEnd == NULL ) { prvHeapInit(); } else { mtCOVERAGE_TEST_MARKER(); } /* Check the requested block size is not so large that the top bit is set. * The top bit of the block size member of the BlockLink_t structure is used * to determine who owns the block - the application or the kernel, so it * must be free. */ if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) { /* The wanted size is increased so it can contain a BlockLink_t * structure in addition to the requested amount of bytes. */ if( xWantedSize > 0 ) { xWantedSize += xHeapStructSize; /* Ensure that blocks are always aligned to the required number of * bytes. */ if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 ) { /* Byte alignment required. */ xWantedSize += ( secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) ); secureportASSERT( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) == 0 ); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) { /* Traverse the list from the start (lowest address) block until * one of adequate size is found. */ pxPreviousBlock = &xStart; pxBlock = xStart.pxNextFreeBlock; while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) { pxPreviousBlock = pxBlock; pxBlock = pxBlock->pxNextFreeBlock; } /* If the end marker was reached then a block of adequate size was * not found. */ if( pxBlock != pxEnd ) { /* Return the memory space pointed to - jumping over the * BlockLink_t structure at its start. */ pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); /* This block is being returned for use so must be taken out * of the list of free blocks. */ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; /* If the block is larger than required it can be split into * two. */ if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE ) { /* This block is to be split into two. Create a new * block following the number of bytes requested. The void * cast is used to prevent byte alignment warnings from the * compiler. */ pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 ); /* Calculate the sizes of two blocks split from the single * block. */ pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; pxBlock->xBlockSize = xWantedSize; /* Insert the new block into the list of free blocks. */ prvInsertBlockIntoFreeList( pxNewBlockLink ); } else { mtCOVERAGE_TEST_MARKER(); } xFreeBytesRemaining -= pxBlock->xBlockSize; if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) { xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; } else { mtCOVERAGE_TEST_MARKER(); } /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ pxBlock->xBlockSize |= xBlockAllocatedBit; pxBlock->pxNextFreeBlock = NULL; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } traceMALLOC( pvReturn, xWantedSize ); #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { extern void vApplicationMallocFailedHook( void ); vApplicationMallocFailedHook(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */ secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 ); return pvReturn; } /*-----------------------------------------------------------*/ void vPortFree( void * pv ) { uint8_t * puc = ( uint8_t * ) pv; BlockLink_t * pxLink; if( pv != NULL ) { /* The memory being freed will have an BlockLink_t structure immediately * before it. */ puc -= xHeapStructSize; /* This casting is to keep the compiler from issuing warnings. */ pxLink = ( void * ) puc; /* Check the block is actually allocated. */ secureportASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); secureportASSERT( pxLink->pxNextFreeBlock == NULL ); if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) { if( pxLink->pxNextFreeBlock == NULL ) { /* The block is being returned to the heap - it is no longer * allocated. */ pxLink->xBlockSize &= ~xBlockAllocatedBit; secureportDISABLE_NON_SECURE_INTERRUPTS(); { /* Add this block to the list of free blocks. */ xFreeBytesRemaining += pxLink->xBlockSize; traceFREE( pv, pxLink->xBlockSize ); prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); } secureportENABLE_NON_SECURE_INTERRUPTS(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } } /*-----------------------------------------------------------*/ size_t xPortGetFreeHeapSize( void ) { return xFreeBytesRemaining; } /*-----------------------------------------------------------*/ size_t xPortGetMinimumEverFreeHeapSize( void ) { return xMinimumEverFreeBytesRemaining; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33/secure/secure_heap.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_HEAP_H__ #define __SECURE_HEAP_H__ /* Standard includes. */ #include /** * @brief Allocates memory from heap. * * @param[in] xWantedSize The size of the memory to be allocated. * * @return Pointer to the memory region if the allocation is successful, NULL * otherwise. */ void * pvPortMalloc( size_t xWantedSize ); /** * @brief Frees the previously allocated memory. * * @param[in] pv Pointer to the memory to be freed. */ void vPortFree( void * pv ); /** * @brief Get the free heap size. * * @return Free heap size. */ size_t xPortGetFreeHeapSize( void ); /** * @brief Get the minimum ever free heap size. * * @return Minimum ever free heap size. */ size_t xPortGetMinimumEverFreeHeapSize( void ); #endif /* __SECURE_HEAP_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33/secure/secure_init.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure init includes. */ #include "secure_init.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Constants required to manipulate the SCB. */ #define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */ #define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL ) #define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS ) #define secureinitSCB_AIRCR_PRIS_POS ( 14UL ) #define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS ) /** * @brief Constants required to manipulate the FPU. */ #define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define secureinitFPCCR_LSPENS_POS ( 29UL ) #define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS ) #define secureinitFPCCR_TS_POS ( 26UL ) #define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS ) #define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */ #define secureinitNSACR_CP10_POS ( 10UL ) #define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS ) #define secureinitNSACR_CP11_POS ( 11UL ) #define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS ) /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { *( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) | ( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) | ( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK ); } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* CP10 = 1 ==> Non-secure access to the Floating Point Unit is * permitted. CP11 should be programmed to the same value as CP10. */ *( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK ); /* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures * that we can enable/disable lazy stacking in port.c file. */ *( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK ); /* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP * registers (S16-S31) are also pushed to stack on exception entry and * restored on exception return. */ *( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK ); } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33/secure/secure_init.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_INIT_H__ #define __SECURE_INIT_H__ /** * @brief De-prioritizes the non-secure exceptions. * * This is needed to ensure that the non-secure PendSV runs at the lowest * priority. Context switch is done in the non-secure PendSV handler. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_DePrioritizeNSExceptions( void ); /** * @brief Sets up the Floating Point Unit (FPU) for Non-Secure access. * * Also sets FPCCR.TS=1 to ensure that the content of the Floating Point * Registers are not leaked to the non-secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_EnableNSFPUAccess( void ); #endif /* __SECURE_INIT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33/secure/secure_port_macros.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_PORT_MACROS_H__ #define __SECURE_PORT_MACROS_H__ /** * @brief Byte alignment requirements. */ #define secureportBYTE_ALIGNMENT 8 #define secureportBYTE_ALIGNMENT_MASK ( 0x0007 ) /** * @brief Macro to declare a function as non-secure callable. */ #if defined( __IAR_SYSTEMS_ICC__ ) #define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root #else #define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) ) #endif /** * @brief Set the secure PRIMASK value. */ #define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Set the non-secure PRIMASK value. */ #define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Read the PSP value in the given variable. */ #define secureportREAD_PSP( pucOutCurrentStackPointer ) \ __asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) ) /** * @brief Set the PSP to the given value. */ #define secureportSET_PSP( pucCurrentStackPointer ) \ __asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) ) /** * @brief Read the PSPLIM value in the given variable. */ #define secureportREAD_PSPLIM( pucOutStackLimit ) \ __asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) ) /** * @brief Set the PSPLIM to the given value. */ #define secureportSET_PSPLIM( pucStackLimit ) \ __asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) ) /** * @brief Set the NonSecure MSP to the given value. */ #define secureportSET_MSP_NS( pucMainStackPointer ) \ __asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) ) /** * @brief Set the CONTROL register to the given value. */ #define secureportSET_CONTROL( ulControl ) \ __asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" ) /** * @brief Read the Interrupt Program Status Register (IPSR) value in the given * variable. */ #define secureportREAD_IPSR( ulIPSR ) \ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) ) /** * @brief PRIMASK value to enable interrupts. */ #define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0 /** * @brief PRIMASK value to disable interrupts. */ #define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1 /** * @brief Disable secure interrupts. */ #define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Disable non-secure interrupts. * * This effectively disables context switches. */ #define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Enable non-secure interrupts. */ #define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL ) /** * @brief Assert definition. */ #define secureportASSERT( x ) \ if( ( x ) == 0 ) \ { \ secureportDISABLE_SECURE_INTERRUPTS(); \ secureportDISABLE_NON_SECURE_INTERRUPTS(); \ for( ; ; ) {; } \ } #endif /* __SECURE_PORT_MACROS_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33_NTZ/non_secure/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /* Portasm includes. */ #include "portasm.h" #if ( configENABLE_TRUSTZONE == 1 ) /* Secure components includes. */ #include "secure_context.h" #include "secure_init.h" #endif /* configENABLE_TRUSTZONE */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /** * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS * on the secure side. The following are the valid configuration seetings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 * * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 * * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 */ #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. #endif /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the SCB. */ #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the FPU. */ #define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) #define portMPU_RLAR_REGION_ENABLE ( 1UL ) /* Enable privileged access to unmapped region. */ #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /*-----------------------------------------------------------*/ /** * @brief The maximum 24-bit number. * * It is needed because the systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /** * @brief A fiddle factor to estimate the number of SysTick counts that would * have occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) /** * @brief Initial EXC_RETURN value. * * FF FF FF FD * 1111 1111 1111 1111 1111 1111 1111 1101 * * Bit[6] - 1 --> The exception was taken from the Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 1 --> The exception was taken to the Secure state. */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else /** * @brief Initial EXC_RETURN value. * * FF FF FF BC * 1111 1111 1111 1111 1111 1111 1011 1100 * * Bit[6] - 0 --> The exception was taken from the Non-Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 0 --> The exception was taken to the Non-Secure state. */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ /** * @brief CONTROL register privileged bit mask. * * Bit[0] in CONTROL register tells the privilege: * Bit[0] = 0 ==> The task is privileged. * Bit[0] = 1 ==> The task is not privileged. */ #define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) /** * @brief Initial CONTROL register values. */ #define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) #define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) /** * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /** * @brief 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /** * @brief If portPRELOAD_REGISTERS then registers will be given an initial value * when a task is created. This helps in debugging at the cost of code size. */ #define portPRELOAD_REGISTERS 1 /** * @brief A task is created without a secure context, and must call * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes * any secure calls. */ #define portNO_SECURE_CONTEXT 0 /*-----------------------------------------------------------*/ /** * @brief Used to catch tasks that attempt to return from their implementing * function. */ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) /** * @brief Setup the Memory Protection Unit (MPU). */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) /** * @brief Setup the Floating Point Unit (FPU). */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ /** * @brief Setup the timer to generate the tick interrupts. * * The implementation in this file is weak to allow application writers to * change the timer used to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /** * @brief Checks whether the current execution context is interrupt. * * @return pdTRUE if the current execution context is interrupt, pdFALSE * otherwise. */ BaseType_t xPortIsInsideInterrupt( void ); /** * @brief Yield the processor. */ void vPortYield( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ void vPortExitCritical( void ) PRIVILEGED_FUNCTION; /** * @brief SysTick handler. */ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; /** * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. */ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Saved as part of the task context to indicate which context the * task is using on the secure side. */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ #if ( configUSE_TICKLESS_IDLE == 1 ) /** * @brief The number of SysTick increments that make up one tick period. */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; /** * @brief The maximum number of tick periods that can be suppressed is * limited by the 24 bit resolution of the SysTick timer. */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; /** * @brief Compensate for the CPU cycles that pass while the SysTick is * stopped (low power functionality only). */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). Artificially force an assert() * to be triggered if configASSERT() is defined, then stop here so * application writers can catch the error. */ configASSERT( ulCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being * defined but never called. ulDummy is used purely to quieten other * warnings about code appearing after this function is called - making * ulDummy volatile makes the compiler think the function could return * and therefore not output an 'unreachable code' warning for code that * appears after it. */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; extern uint32_t * __unprivileged_flash_start__; extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* if defined( __ARMCC_VERSION ) */ /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; extern uint32_t __unprivileged_flash_start__[]; extern uint32_t __unprivileged_flash_end__[]; extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check that the MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* MAIR0 - Index 0. */ portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); /* MAIR0 - Index 1. */ portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* Setup privileged flash as Read Only so that privileged tasks can * read it but not modify. */ portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged flash as Read Only by both privileged and * unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged syscalls flash as Read Only by both privileged * and unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup RAM containing kernel data for privileged access only. */ portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Enable mem fault. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; /* Enable MPU with privileged background access i.e. unmapped * regions have privileged access. */ portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) { /* Enable non-secure access to the FPU. */ SecureInit_EnableNSFPUAccess(); } #endif /* configENABLE_TRUSTZONE */ /* CP10 = 11 ==> Full access to FPU i.e. both privileged and * unprivileged code should be able to access FPU. CP11 should be * programmed to the same value as CP10. */ *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) ); /* ASPEN = 1 ==> Hardware should automatically preserve floating point * context on exception entry and restore on exception return. * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ void vPortYield( void ) /* PRIVILEGED_FUNCTION */ { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ { portDISABLE_INTERRUPTS(); ulCriticalNesting++; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ { configASSERT( ulCriticalNesting ); ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { #if ( configENABLE_MPU == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ #endif /* configENABLE_MPU */ uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) uint32_t ulR0, ulR1; extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ #endif /* configENABLE_TRUSTZONE */ uint8_t ucSVCNumber; /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ ulPC = pulCallerStackAddress[ 6 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { #if ( configENABLE_TRUSTZONE == 1 ) case portSVC_ALLOCATE_SECURE_CONTEXT: /* R0 contains the stack size passed as parameter to the * vPortAllocateSecureContext function. */ ulR0 = pulCallerStackAddress[ 0 ]; #if ( configENABLE_MPU == 1 ) { /* Read the CONTROL register value. */ __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); /* The task that raised the SVC is privileged if Bit[0] * in the CONTROL register is 0. */ ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: /* R0 contains TCB being freed and R1 contains the secure * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) { /* De-prioritize the non-secure exceptions so that the * non-secure pendSV runs at the lowest priority. */ SecureInit_DePrioritizeNSExceptions(); /* Initialize the secure context management system. */ SecureContext_Init(); } #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_FPU == 1 ) { /* Setup the Floating Point Unit (FPU). */ prvSetupFPU(); } #endif /* configENABLE_FPU */ /* Setup the context of the first task so that the first task starts * executing. */ vRestoreContextOfFirstTask(); break; #if ( configENABLE_MPU == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the svc was raised from any of * the system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { vRaisePrivilege(); } break; #endif /* configENABLE_MPU */ default: /* Incorrect SVC call. */ configASSERT( pdFALSE ); } } /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #if ( configENABLE_MPU == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /* *INDENT-ON* */ { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #endif /* portPRELOAD_REGISTERS */ return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ prvSetupMPU(); } #endif /* configENABLE_MPU */ /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; /* Start the first task. */ vStartFirstTask(); /* Should never get here as the tasks will now be executing. Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* Setup MAIR0. */ xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ if( ulStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged * SRAM is already protected using an MPU region and ARMv8-M does * not allow overlapping MPU regions. */ if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) { xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; } else { /* Define the region that allows access to the stack. */ ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); } } /* User supplied configurable regions. */ for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) { /* If xRegions is NULL i.e. the task has not specified any MPU * region, the else part ensures that all the configurable MPU * regions are invalidated. */ if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) { /* Translate the generic region definition contained in xRegions * into the ARMv8 specific MPU settings that are then stored in * xMPUSettings. */ ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; /* Start address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ); /* RO/RW. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); } else { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); } /* XN. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); } /* End Address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { /* Attr1 in MAIR0 is configured as device memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; } else { /* Attr0 in MAIR0 is configured as normal memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; } } else { /* Invalidate the region. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; } lIndex++; } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. Interrupt Program * Status Register (IPSR) holds the exception number of the currently-executing * exception or zero for Thread mode.*/ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION * is defined correctly and privileged functions are placed in correct sections. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Portasm includes. */ #include "portasm.h" /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r4, [r2] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r3, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #4 \n"/* r3 = 4. */ " str r3, [r2] \n"/* Program RNR = 4. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #8 \n"/* r3 = 8. */ " str r3, [r2] \n"/* Program RNR = 8. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #12 \n"/* r3 = 12. */ " str r3, [r2] \n"/* Program RNR = 12. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " str r4, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ " msr control, r2 \n"/* Set this task's CONTROL value. */ " 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. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " bx r3 \n"/* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ " movs r1, #2 \n"/* r1 = 2. */ " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ " 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. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " bx r2 \n"/* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst2: .word 0xe000ed94 \n" "xMAIR0Const2: .word 0xe000edc0 \n" "xRNRConst2: .word 0xe000ed98 \n" "xRBARConst2: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ " ite ne \n" " 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. */ " bx lr \n"/* Return. */ " \n" " .align 4 \n" ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* Read the CONTROL register. */ " bic r0, #1 \n"/* Clear the bit 0. */ " msr control, r0 \n"/* Write back the new CONTROL value. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vResetPrivilege( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " orr r0, #1 \n"/* r0 = r0 | 1. */ " msr control, r0 \n"/* CONTROL = r0. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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"/* The first entry in vector table is stack pointer. */ " msr msp, r0 \n"/* Set the MSP back to the start of the stack. */ " cpsie i \n"/* Globally enable interrupts. */ " cpsie f \n" " dsb \n" " isb \n" " svc %0 \n"/* System call to start the first task. */ " nop \n" " \n" " .align 4 \n" "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } /*-----------------------------------------------------------*/ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n"/* Return. */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); } /*-----------------------------------------------------------*/ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " msr basepri, r0 \n"/* basepri = ulMask. */ " dsb \n" " isb \n" " bx lr \n"/* Return. */ ::: "memory" ); } /*-----------------------------------------------------------*/ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, psp \n"/* Read PSP in r0. */ #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. */ " it eq \n" " vstmdbeq r0!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r2, control \n"/* r2 = CONTROL. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r1-r11} \n"/* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ #else /* configENABLE_MPU */ " mrs r2, psplim \n"/* r2 = PSPLIM. */ " 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. */ #endif /* configENABLE_MPU */ " \n" " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " str r0, [r1] \n"/* Save the new top of stack in TCB. */ " \n" " mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" " mov r0, #0 \n"/* r0 = 0. */ " msr basepri, r0 \n"/* Enable interrupts. */ " \n" " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r4, [r2] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r3, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #4 \n"/* r3 = 4. */ " str r3, [r2] \n"/* Program RNR = 4. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #8 \n"/* r3 = 8. */ " str r3, [r2] \n"/* Program RNR = 8. */ " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #12 \n"/* r3 = 12. */ " str r3, [r2] \n"/* Program RNR = 12. */ " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " str r4, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldmia r0!, {r1-r11} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ #else /* configENABLE_MPU */ " ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #endif /* configENABLE_MPU */ " \n" #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. */ " it eq \n" " vldmiaeq r0!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" #if ( configENABLE_MPU == 1 ) " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ " msr control, r2 \n"/* Restore the CONTROL register value for the task. */ #else /* configENABLE_MPU */ " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ #endif /* configENABLE_MPU */ " msr psp, r0 \n"/* Remember the new top of stack for the task. */ " bx r3 \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst: .word 0xe000ed94 \n" "xMAIR0Const: .word 0xe000edc0 \n" "xRNRConst: .word 0xe000ed98 \n" "xRBARConst: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } /*-----------------------------------------------------------*/ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " tst lr, #4 \n" " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" " ldr r1, svchandler_address_const \n" " bx r1 \n" " \n" " .align 4 \n" "svchandler_address_const: .word vPortSVCHandler_C \n" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORT_ASM_H__ #define __PORT_ASM_H__ /* Scheduler includes. */ #include "FreeRTOS.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /** * @brief Restore the context of the first task so that the first task starts * executing. */ void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * * @note This is a privileged function and should only be called from the kenrel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Starts the first task. */ void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Disables interrupts. */ uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Enables interrupts. */ void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief PendSV Exception handler. */ void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief SVC Handler. */ void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Allocate a Secure context for the calling task. * * @param[in] ulSecureStackSize The size of the stack to be allocated on the * secure side for the calling task. */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); /** * @brief Free the task's secure context. * * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. */ void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* __PORT_ASM_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M33" #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACROCOMMON_H #define PORTMACROCOMMON_H #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_FPU #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. #endif /* configENABLE_FPU */ #ifndef configENABLE_MPU #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. #endif /* configENABLE_MPU */ #ifndef configENABLE_TRUSTZONE #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ /** * @brief Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif #define portHAS_STACK_OVERFLOW_CHECKING 1 /*-----------------------------------------------------------*/ /** * @brief Extern declarations. */ extern BaseType_t xPortIsInsideInterrupt( void ); extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; #if ( configENABLE_TRUSTZONE == 1 ) extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_MPU == 1 ) extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief MPU specific constants. */ #if ( configENABLE_MPU == 1 ) #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #else #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* MPU regions. */ #define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_RAM_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ /* Device memory attributes used in MPU_MAIR registers. * * 8-bit values encoded as follows: * Bit[7:4] - 0000 - Device Memory * Bit[3:2] - 00 --> Device-nGnRnE * 01 --> Device-nGnRE * 10 --> Device-nGRE * 11 --> Device-GRE * Bit[1:0] - 00, Reserved. */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ /* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ /* Attributes used in MPU_RBAR registers. */ #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ /** * @brief Settings to define an MPU region. */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */ } MPURegionSettings_t; /** * @brief MPU settings as stored in the TCB. */ typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ } xMPU_SETTINGS; /*-----------------------------------------------------------*/ /** * @brief SVC numbers. */ #define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 /*-----------------------------------------------------------*/ /** * @brief Scheduler utilities. */ #define portYIELD() vPortYield() #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /** * @brief Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /** * @brief Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Allocate a secure context for the task. * * 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 context before it calls any secure function. * * @param[in] ulSecureStackSize The size of the secure stack to be allocated. */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) /** * @brief Called when a task is deleted to delete the task's secure context, * if it has one. * * @param[in] pxTCB The TCB of the task being deleted. */ #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. * * 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, * the privilege is not raised. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() #else #define portIS_PRIVILEGED() #define portRAISE_PRIVILEGE() #define portRESET_PRIVILEGE() #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief Barriers. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACROCOMMON_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM3_MPU/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM3 MPU port. *----------------------------------------------------------*/ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK ( 1UL << 2UL ) #else /* The way the SysTick is clocked is not modified in case it is not the same * as the core. */ #define portNVIC_SYSTICK_CLK ( 0 ) #endif #ifndef configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS #warning "configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS is not defined. We recommend defining it to 0 in FreeRTOSConfig.h for better security." #define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1 #endif /* Constants required to access and manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SHPR2_REG ( *( ( volatile uint32_t * ) 0xe000ed1c ) ) #define portNVIC_SYS_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portNVIC_MEM_FAULT_ENABLE ( 1UL << 16UL ) /* Constants required to access and manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_REGION_BASE_ADDRESS_REG ( *( ( volatile uint32_t * ) 0xe000ed9C ) ) #define portMPU_REGION_ATTRIBUTE_REG ( *( ( volatile uint32_t * ) 0xe000edA0 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portEXPECTED_MPU_TYPE_VALUE ( 8UL << 8UL ) /* 8 regions, unified. */ #define portMPU_ENABLE ( 0x01UL ) #define portMPU_BACKGROUND_ENABLE ( 1UL << 2UL ) #define portPRIVILEGED_EXECUTION_START_ADDRESS ( 0UL ) #define portMPU_REGION_VALID ( 0x10UL ) #define portMPU_REGION_ENABLE ( 0x01UL ) #define portPERIPHERALS_START_ADDRESS 0x40000000UL #define portPERIPHERALS_END_ADDRESS 0x5FFFFFFFUL /* Constants required to access and manipulate the SysTick. */ #define portNVIC_SYSTICK_INT ( 0x00000002UL ) #define portNVIC_SYSTICK_ENABLE ( 0x00000001UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) #define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 ) #define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) #define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) ) #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) /* Offsets in the stack to the parameters when inside the SVC handler. */ #define portOFFSET_TO_PC ( 6 ) /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) /*-----------------------------------------------------------*/ /* * Configure a number of standard MPU regions that are used by all tasks. */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; /* * Return the smallest MPU region size that a given number of bytes will fit * into. The region size is returned as the value that should be programmed * into the region attribute register for that region. */ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) PRIVILEGED_FUNCTION; /* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ); /* * Standard FreeRTOS exception handlers. */ void xPortPendSVHandler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; void xPortSysTickHandler( void ) __attribute__( ( optimize( "3" ) ) ) PRIVILEGED_FUNCTION; void vPortSVCHandler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /* * Starts the scheduler by restoring the context of the first task to run. */ static void prvRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /* * C portion of the SVC handler. The SVC handler is split between an asm entry * and a C wrapper for simplicity of coding and maintenance. */ static void prvSVCHandler( uint32_t * pulRegisters ) __attribute__( ( noinline ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Enter critical section. */ #if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL; #else void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; #endif /** * @brief Exit from critical section. */ #if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL; #else void vPortExitCritical( void ) PRIVILEGED_FUNCTION; #endif /*-----------------------------------------------------------*/ /* Each task maintains its own interrupt status in the critical nesting * variable. Note this is not saved as part of the task context as context * switches can only occur when uxCriticalNesting is zero. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. */ #if ( configASSERT_DEFINED == 1 ) static uint8_t ucMaxSysCallPriority = 0; static uint32_t ulMaxPRIGROUPValue = 0; static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ pxTopOfStack--; *pxTopOfStack = 0; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_IF_PRIVILEGED; } else { *pxTopOfStack = portINITIAL_CONTROL_IF_UNPRIVILEGED; } return pxTopOfStack; } /*-----------------------------------------------------------*/ void vPortSVCHandler( void ) { /* Assumes psp was in use. */ __asm volatile ( #ifndef USE_PROCESS_STACK /* Code should not be required if a main() is using the process stack. */ " tst lr, #4 \n" " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" #else " mrs r0, psp \n" #endif " b %0 \n" ::"i" ( prvSVCHandler ) : "r0", "memory" ); } /*-----------------------------------------------------------*/ static void prvSVCHandler( uint32_t * pulParam ) { uint8_t ucSVCNumber; uint32_t ulPC; #if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* #if defined( __ARMCC_VERSION ) */ #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ /* The stack contains: r0, r1, r2, r3, r12, LR, PC and xPSR. The first * argument (r0) is pulParam[ 0 ]. */ ulPC = pulParam[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { case portSVC_START_SCHEDULER: portNVIC_SHPR2_REG |= portNVIC_SVC_PRI; prvRestoreContextOfFirstTask(); break; case portSVC_YIELD: portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required * but do ensure the code is completely * within the specified behaviour for the * architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); break; #if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the * svc was raised from any of the * system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { __asm volatile ( " mrs r1, control \n"/* Obtain current control value. */ " bic r1, #1 \n"/* Set privilege bit. */ " msr control, r1 \n"/* Write back new control value. */ ::: "r1", "memory" ); } break; #else /* if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ case portSVC_RAISE_PRIVILEGE: __asm volatile ( " mrs r1, control \n"/* Obtain current control value. */ " bic r1, #1 \n"/* Set privilege bit. */ " msr control, r1 \n"/* Write back new control value. */ ::: "r1", "memory" ); break; #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ default: /* Unknown SVC call. */ break; } } /*-----------------------------------------------------------*/ static void prvRestoreContextOfFirstTask( void ) { __asm volatile ( " ldr r0, =0xE000ED08 \n"/* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" " ldr r0, [r0] \n" " msr msp, r0 \n"/* Set the msp back to the start of the stack. */ " ldr r3, pxCurrentTCBConst2 \n"/* Restore the context. */ " ldr r1, [r3] \n" " ldr r0, [r1] \n"/* The first item in the TCB is the task top of stack. */ " add r1, r1, #4 \n"/* Move onto the second item in the TCB... */ " \n" " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " bic r3, #1 \n"/* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ " str r3, [r2] \n"/* Disable MPU. */ " \n" " ldr r2, =0xe000ed9c \n"/* Region Base Address register. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers. */ " stmia r2!, {r4-r11} \n"/* Write 4 sets of MPU registers. */ " \n" " ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " orr r3, #1 \n"/* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ " str r3, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ " \n" " ldmia r0!, {r3, r4-r11} \n"/* Pop the registers that are not automatically saved on exception entry. */ " msr control, r3 \n" " msr psp, r0 \n"/* Restore the task stack pointer. */ " mov r0, #0 \n" " msr basepri, r0 \n" " ldr r14, =0xfffffffd \n"/* Load exec return code. */ " bx r14 \n" " \n" " .ltorg \n"/* Assemble current literal pool to avoid offset-out-of-bound errors with lto. */ " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" ); } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API * functions can be called. ISR safe functions are those that end in * "FromISR". FreeRTOS maintains separate thread and ISR API functions * to ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { ulMaxPRIGROUPValue--; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); } #endif /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; /* Restore the clobbered interrupt priority register to its original * value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* Make PendSV and SysTick the same priority as the kernel, and the SVC * handler higher priority so it can be used to exit a critical section (where * lower priorities are masked). */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Configure the regions in the MPU that are common to all tasks. */ prvSetupMPU(); /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Start the first task. */ __asm volatile ( " ldr r0, =0xE000ED08 \n"/* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" " ldr r0, [r0] \n" " msr msp, r0 \n"/* Set the msp back to the start of the stack. */ " cpsie i \n"/* Globally enable interrupts. */ " cpsie f \n" " dsb \n" " isb \n" " svc %0 \n"/* System call to start first task. */ " nop \n" " .ltorg \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { #if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); portDISABLE_INTERRUPTS(); uxCriticalNesting++; portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { portDISABLE_INTERRUPTS(); uxCriticalNesting++; } #else portDISABLE_INTERRUPTS(); uxCriticalNesting++; #endif } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { #if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } #else configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } #endif } /*-----------------------------------------------------------*/ void xPortPendSVHandler( void ) { /* This is a naked function. */ __asm volatile ( " mrs r0, psp \n" " \n" " ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */ " ldr r2, [r3] \n" " \n" " mrs r1, control \n" " stmdb r0!, {r1, r4-r11} \n"/* Save the remaining registers. */ " str r0, [r2] \n"/* Save the new top of stack into the first member of the TCB. */ " \n" " stmdb sp!, {r3, r14} \n" " mov r0, %0 \n" " msr basepri, r0 \n" " dsb \n" " isb \n" " bl vTaskSwitchContext \n" " mov r0, #0 \n" " msr basepri, r0 \n" " ldmia sp!, {r3, r14} \n" " \n"/* Restore the context. */ " ldr r1, [r3] \n" " ldr r0, [r1] \n"/* The first item in the TCB is the task top of stack. */ " add r1, r1, #4 \n"/* Move onto the second item in the TCB... */ " \n" " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " bic r3, #1 \n"/* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ " str r3, [r2] \n"/* Disable MPU. */ " \n" " ldr r2, =0xe000ed9c \n"/* Region Base Address register. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers. */ " stmia r2!, {r4-r11} \n"/* Write 4 sets of MPU registers. */ " \n" " ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " orr r3, #1 \n"/* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ " str r3, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ " \n" " ldmia r0!, {r3, r4-r11} \n"/* Pop the registers that are not automatically saved on exception entry. */ " msr control, r3 \n" " \n" " msr psp, r0 \n" " bx r14 \n" " \n" " .ltorg \n"/* Assemble current literal pool to avoid offset-out-of-bound errors with lto. */ " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { uint32_t ulDummy; ulDummy = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy ); } /*-----------------------------------------------------------*/ /* * Setup the systick timer to generate the tick interrupts at the required * frequency. */ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) { /* Stop and clear the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE ); } /*-----------------------------------------------------------*/ static void prvSetupMPU( void ) { extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __FLASH_segment_start__[]; extern uint32_t __FLASH_segment_end__[]; extern uint32_t __privileged_data_start__[]; extern uint32_t __privileged_data_end__[]; /* Check the expected MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* First setup the unprivileged flash for unprivileged read only access. */ portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __FLASH_segment_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | ( portUNPRIVILEGED_FLASH_REGION ); portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_READ_ONLY ) | ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | ( prvGetMPURegionSizeSetting( ( uint32_t ) __FLASH_segment_end__ - ( uint32_t ) __FLASH_segment_start__ ) ) | ( portMPU_REGION_ENABLE ); /* Setup the privileged flash for privileged only access. This is where * the kernel code is * placed. */ portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_functions_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | ( portPRIVILEGED_FLASH_REGION ); portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_PRIVILEGED_READ_ONLY ) | ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | ( prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_functions_end__ - ( uint32_t ) __privileged_functions_start__ ) ) | ( portMPU_REGION_ENABLE ); /* Setup the privileged data RAM region. This is where the kernel data * is placed. */ portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | ( portPRIVILEGED_RAM_REGION ); portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | ( portMPU_REGION_EXECUTE_NEVER ) | prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_data_end__ - ( uint32_t ) __privileged_data_start__ ) | ( portMPU_REGION_ENABLE ); /* By default allow everything to access the general peripherals. The * system peripherals and registers are protected. */ portMPU_REGION_BASE_ADDRESS_REG = ( portPERIPHERALS_START_ADDRESS ) | ( portMPU_REGION_VALID ) | ( portGENERAL_PERIPHERALS_REGION ); portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_READ_WRITE | portMPU_REGION_EXECUTE_NEVER ) | ( prvGetMPURegionSizeSetting( portPERIPHERALS_END_ADDRESS - portPERIPHERALS_START_ADDRESS ) ) | ( portMPU_REGION_ENABLE ); /* Enable the memory fault exception. */ portNVIC_SYS_CTRL_STATE_REG |= portNVIC_MEM_FAULT_ENABLE; /* Enable the MPU with the background region configured. */ portMPU_CTRL_REG |= ( portMPU_ENABLE | portMPU_BACKGROUND_ENABLE ); } } /*-----------------------------------------------------------*/ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) { uint32_t ulRegionSize, ulReturnValue = 4; /* 32 is the smallest region size, 31 is the largest valid value for * ulReturnValue. */ for( ulRegionSize = 32UL; ulReturnValue < 31UL; ( ulRegionSize <<= 1UL ) ) { if( ulActualSizeInBytes <= ulRegionSize ) { break; } else { ulReturnValue++; } } /* Shift the code by one before returning so it can be written directly * into the the correct bit position of the attribute register. */ return( ulReturnValue << 1UL ); } /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " mrs r0, control \n"/* r0 = CONTROL. */ " tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ " ite ne \n" " 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. */ " bx lr \n"/* Return. */ " \n" " .align 4 \n" ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vResetPrivilege( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " mrs r0, control \n"/* r0 = CONTROL. */ " orr r0, #1 \n"/* r0 = r0 | 1. */ " msr control, r0 \n"/* CONTROL = r0. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { extern uint32_t __SRAM_segment_start__[]; extern uint32_t __SRAM_segment_end__[]; extern uint32_t __privileged_data_start__[]; extern uint32_t __privileged_data_end__[]; int32_t lIndex; uint32_t ul; if( xRegions == NULL ) { /* No MPU regions are specified so allow access to all RAM. */ xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = ( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | ( portSTACK_REGION ); /* Region number. */ xMPUSettings->xRegion[ 0 ].ulRegionAttribute = ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | ( portMPU_REGION_EXECUTE_NEVER ) | ( prvGetMPURegionSizeSetting( ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__ ) ) | ( portMPU_REGION_ENABLE ); /* Invalidate user configurable regions. */ for( ul = 1UL; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) { xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID ); xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; } } else { /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that the * stack region has already been configured. */ if( ulStackDepth > 0 ) { /* Define the region that allows access to the stack. */ xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = ( ( uint32_t ) pxBottomOfStack ) | ( portMPU_REGION_VALID ) | ( portSTACK_REGION ); /* Region number. */ xMPUSettings->xRegion[ 0 ].ulRegionAttribute = ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ) | ( prvGetMPURegionSizeSetting( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) ) | ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | ( portMPU_REGION_ENABLE ); } lIndex = 0; for( ul = 1UL; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) { if( ( xRegions[ lIndex ] ).ulLengthInBytes > 0UL ) { /* Translate the generic region definition contained in * xRegions into the CM3 specific MPU settings that are then * stored in xMPUSettings. */ xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) | ( portMPU_REGION_VALID ) | ( ul - 1UL ); /* Region number. */ xMPUSettings->xRegion[ ul ].ulRegionAttribute = ( prvGetMPURegionSizeSetting( xRegions[ lIndex ].ulLengthInBytes ) ) | ( xRegions[ lIndex ].ulParameters ) | ( portMPU_REGION_ENABLE ); } else { /* Invalidate the region. */ xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID ); xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; } lIndex++; } } } /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); /* Is the interrupt number a user defined interrupt? */ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /* Look up the interrupt's priority. */ ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Interrupts that use the FreeRTOS API must not be left at their * default priority of zero as that is the highest possible priority, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * and therefore also guaranteed to be invalid. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } /* Priority grouping: The interrupt controller (NVIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined * to be pre-emption priority bits. The following assertion will fail if * this is not the case (if some bits represent a sub-priority). * * If the application only uses CMSIS libraries for interrupt * configuration then the correct setting can be achieved on all Cortex-M * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * scheduler. Note however that some vendor specific peripheral libraries * assume a non-zero priority group setting, in which cases using a value * of zero will result in unpredicable behaviour. */ configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); } #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM3_MPU/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* MPU specific constants. */ #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #define portMPU_REGION_READ_WRITE ( 0x03UL << 24UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 0x05UL << 24UL ) #define portMPU_REGION_READ_ONLY ( 0x06UL << 24UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0x01UL << 24UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ( 0x02UL << 24UL ) #define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL ) #define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL ) #define portGENERAL_PERIPHERALS_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portUNPRIVILEGED_FLASH_REGION ( 5UL ) #define portPRIVILEGED_FLASH_REGION ( 6UL ) #define portPRIVILEGED_RAM_REGION ( 7UL ) #define portFIRST_CONFIGURABLE_REGION ( 0UL ) #define portLAST_CONFIGURABLE_REGION ( 2UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " ::: "r0", "memory" ) typedef struct MPU_REGION_REGISTERS { uint32_t ulRegionBaseAddress; uint32_t ulRegionAttribute; } xMPU_REGION_REGISTERS; /* Plus 1 to create space for the stack region. */ typedef struct MPU_SETTINGS { xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ]; } xMPU_SETTINGS; /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ /* SVC numbers for various services. */ #define portSVC_START_SCHEDULER 0 #define portSVC_YIELD 1 #define portSVC_RAISE_PRIVILEGE 2 /* Scheduler utilities. */ #define portYIELD() __asm volatile ( " SVC %0 \n"::"i" ( portSVC_YIELD ) : "memory" ) #define portYIELD_WITHIN_API() \ { \ /* Set a PendSV to request a context switch. */ \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ \ /* Barriers are normally not required but do ensure the code is completely \ * within the specified behaviour for the architecture. */ \ __asm volatile ( "dsb" ::: "memory" ); \ __asm volatile ( "isb" ); \ } #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x ) #define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() #define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /* 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 * (which build with all the ports) will build. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Generic helper function. */ __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) { uint8_t ucReturn; __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" ); return ucReturn; } /* Check the configuration. */ #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. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /*-----------------------------------------------------------*/ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* portNOP() is not required by this port. */ #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif /*-----------------------------------------------------------*/ extern BaseType_t xIsPrivileged( void ); extern void vResetPrivilege( void ); /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() /*-----------------------------------------------------------*/ portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ portFORCE_INLINE static void vPortRaiseBASEPRI( void ) { uint32_t ulNewBASEPRI; __asm volatile ( " mov %0, %1 \n"\ " msr basepri, %0 \n"\ " isb \n"\ " dsb \n"\ : "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); } /*-----------------------------------------------------------*/ portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) { uint32_t ulOriginalBASEPRI, ulNewBASEPRI; __asm volatile ( " mrs %0, basepri \n"\ " mov %1, %2 \n"\ " msr basepri, %1 \n"\ " isb \n"\ " dsb \n"\ : "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); /* This return will not be reached but is necessary to prevent compiler * warnings. */ return ulOriginalBASEPRI; } /*-----------------------------------------------------------*/ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) { __asm volatile ( " msr basepri, %0 "::"r" ( ulNewMaskValue ) : "memory" ); } /*-----------------------------------------------------------*/ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #ifndef configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY #warning "configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY is not defined. We recommend defining it to 1 in FreeRTOSConfig.h for better security. https://www.FreeRTOS.org/FreeRTOS-V10.3.x.html" #define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 0 #endif /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM4F/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM4F port. *----------------------------------------------------------*/ /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #ifndef __VFP_FP__ #error This port can only be used when the project options are configured to enable hardware floating point support. #endif /* Constants required to manipulate the core. Registers first... */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) /* ...then bits in the registers. */ #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) /* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7 * r0p1 port. */ #define portCPUID ( *( ( volatile uint32_t * ) 0xE000ed00 ) ) #define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) #define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) #define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) ) #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ #define portVECTACTIVE_MASK ( 0xFFUL ) /* Constants required to manipulate the VFP. */ #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_EXC_RETURN ( 0xfffffffd ) /* The systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) /* A fiddle factor to estimate the number of SysTick counts that would have * occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /* Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /* 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 * debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ); /* * Exception handlers. */ void xPortPendSVHandler( void ) __attribute__( ( naked ) ); void xPortSysTickHandler( void ); void vPortSVCHandler( void ) __attribute__( ( naked ) ); /* * Start first task is a separate function so it can be tested in isolation. */ static void prvPortStartFirstTask( void ) __attribute__( ( naked ) ); /* * Function to enable the VFP. */ static void vPortEnableVFP( void ) __attribute__( ( naked ) ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* Each task maintains its own interrupt status in the critical nesting * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* * The number of SysTick increments that make up one tick period. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulTimerCountsForOneTick = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * The maximum number of tick periods that can be suppressed is limited by the * 24 bit resolution of the SysTick timer. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t xMaximumPossibleSuppressedTicks = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Compensate for the CPU cycles that pass while the SysTick is stopped (low * power functionality only. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. */ #if ( configASSERT_DEFINED == 1 ) static uint8_t ucMaxSysCallPriority = 0; static uint32_t ulMaxPRIGROUPValue = 0; static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ /* Offset added to account for the way the MCU uses the stack on entry/exit * of interrupts, and to ensure alignment. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ /* Save code space by skipping register initialisation. */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ /* A save method is being used that requires each task to maintain its * own exec return value. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). * * Artificially force an assert() to be triggered if configASSERT() is * defined, then stop here so application writers can catch the error. */ configASSERT( uxCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being defined * but never called. ulDummy is used purely to quieten other warnings * about code appearing after this function is called - making ulDummy * volatile makes the compiler think the function could return and * therefore not output an 'unreachable code' warning for code that appears * after it. */ } } /*-----------------------------------------------------------*/ void vPortSVCHandler( void ) { __asm volatile ( " ldr r3, pxCurrentTCBConst2 \n"/* Restore the context. */ " ldr r1, [r3] \n"/* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. */ " ldmia r0!, {r4-r11, r14} \n"/* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ " msr psp, r0 \n"/* Restore the task stack pointer. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n" " bx r14 \n" " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" ); } /*-----------------------------------------------------------*/ static void prvPortStartFirstTask( void ) { /* Start the first task. This also clears the bit that indicates the FPU is * in use in case the FPU was used before the scheduler was started - which * would otherwise result in the unnecessary leaving of space in the SVC stack * for lazy saving of FPU registers. */ __asm volatile ( " ldr r0, =0xE000ED08 \n"/* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" " ldr r0, [r0] \n" " msr msp, r0 \n"/* Set the msp back to the start of the stack. */ " mov r0, #0 \n"/* Clear the bit that indicates the FPU is in use, see comment above. */ " msr control, r0 \n" " cpsie i \n"/* Globally enable interrupts. */ " cpsie f \n" " dsb \n" " isb \n" " svc 0 \n"/* System call to start first task. */ " nop \n" " .ltorg \n" ); } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); /* This port can be used on all revisions of the Cortex-M7 core other than * the r0p1 parts. r0p1 parts should use the port from the * /source/portable/GCC/ARM_CM7/r0p1 directory. */ configASSERT( portCPUID != portCORTEX_M7_r0p1_ID ); configASSERT( portCPUID != portCORTEX_M7_r0p0_ID ); #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API * functions can be called. ISR safe functions are those that end in * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { ulMaxPRIGROUPValue--; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); } #endif /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; /* Restore the clobbered interrupt priority register to its original * value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Ensure the VFP is enabled - it should be anyway. */ vPortEnableVFP(); /* Lazy save always. */ *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; /* Start the first task. */ prvPortStartFirstTask(); /* Should never get here as the tasks will now be executing! Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimisation does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); uxCriticalNesting++; /* 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 * 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 * assert function also uses a critical section. */ if( uxCriticalNesting == 1 ) { configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void xPortPendSVHandler( void ) { /* This is a naked function. */ __asm volatile ( " mrs r0, psp \n" " isb \n" " \n" " ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */ " ldr r2, [r3] \n" " \n" " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, push high vfp registers. */ " it eq \n" " vstmdbeq r0!, {s16-s31} \n" " \n" " stmdb r0!, {r4-r11, r14} \n"/* Save the core registers. */ " str r0, [r2] \n"/* Save the new top of stack into the first member of the TCB. */ " \n" " stmdb sp!, {r0, r3} \n" " mov r0, %0 \n" " msr basepri, r0 \n" " dsb \n" " isb \n" " bl vTaskSwitchContext \n" " mov r0, #0 \n" " msr basepri, r0 \n" " ldmia sp!, {r0, r3} \n" " \n" " ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. */ " ldr r0, [r1] \n" " \n" " ldmia r0!, {r4-r11, r14} \n"/* Pop the core registers. */ " \n" " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, pop the high vfp registers too. */ " it eq \n" " vldmiaeq r0!, {s16-s31} \n" " \n" " msr psp, r0 \n" " isb \n" " \n" #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */ #if WORKAROUND_PMU_CM001 == 1 " push { r14 } \n" " pop { pc } \n" #endif #endif " \n" " bx r14 \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { /* The SysTick runs at the lowest interrupt priority, so when this interrupt * executes all interrupts must be unmasked. There is therefore no need to * save and then restore the interrupt mask value as its value is already * known. */ portDISABLE_INTERRUPTS(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* A context switch is required. Context switching is performed in * the PendSV interrupt. Pend the PendSV interrupt. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portENABLE_INTERRUPTS(); } /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* #if configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ /* * Setup the systick timer to generate the tick interrupts at the required * frequency. */ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and clear the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); } /*-----------------------------------------------------------*/ /* This is a naked function. */ static void vPortEnableVFP( void ) { __asm volatile ( " ldr.w r0, =0xE000ED88 \n"/* The FPU enable bits are in the CPACR. */ " ldr r1, [r0] \n" " \n" " orr r1, r1, #( 0xf << 20 ) \n"/* Enable CP10 and CP11 coprocessors, then save back. */ " str r1, [r0] \n" " bx r14 \n" " .ltorg \n" ); } /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); /* Is the interrupt number a user defined interrupt? */ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /* Look up the interrupt's priority. */ ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Interrupts that use the FreeRTOS API must not be left at their * default priority of zero as that is the highest possible priority, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * and therefore also guaranteed to be invalid. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } /* Priority grouping: The interrupt controller (NVIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined * to be pre-emption priority bits. The following assertion will fail if * this is not the case (if some bits represent a sub-priority). * * If the application only uses CMSIS libraries for interrupt * configuration then the correct setting can be achieved on all Cortex-M * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * scheduler. Note however that some vendor specific peripheral libraries * assume a non-zero priority group setting, in which cases using a value * of zero will result in unpredictable behaviour. */ configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); } #endif /* configASSERT_DEFINED */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM4F/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ #define portYIELD() \ { \ /* Set a PendSV to request a context switch. */ \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ \ /* Barriers are normally not required but do ensure the code is completely \ * within the specified behaviour for the architecture. */ \ __asm volatile ( "dsb" ::: "memory" ); \ __asm volatile ( "isb" ); \ } #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x ) #define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() #define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /* 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 * (which build with all the ports) will build. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Generic helper function. */ __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) { uint8_t ucReturn; __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" ); return ucReturn; } /* Check the configuration. */ #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. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /*-----------------------------------------------------------*/ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* portNOP() is not required by this port. */ #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ portFORCE_INLINE static void vPortRaiseBASEPRI( void ) { uint32_t ulNewBASEPRI; __asm volatile ( " mov %0, %1 \n"\ " msr basepri, %0 \n"\ " isb \n"\ " dsb \n"\ : "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); } /*-----------------------------------------------------------*/ portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) { uint32_t ulOriginalBASEPRI, ulNewBASEPRI; __asm volatile ( " mrs %0, basepri \n"\ " mov %1, %2 \n"\ " msr basepri, %1 \n"\ " isb \n"\ " dsb \n"\ : "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); /* This return will not be reached but is necessary to prevent compiler * warnings. */ return ulOriginalBASEPRI; } /*-----------------------------------------------------------*/ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) { __asm volatile ( " msr basepri, %0 "::"r" ( ulNewMaskValue ) : "memory" ); } /*-----------------------------------------------------------*/ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM4_MPU/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM4 MPU port. *----------------------------------------------------------*/ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #ifndef __VFP_FP__ #error This port can only be used when the project options are configured to enable hardware floating point support. #endif #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK ( 1UL << 2UL ) #else /* The way the SysTick is clocked is not modified in case it is not the same * as the core. */ #define portNVIC_SYSTICK_CLK ( 0 ) #endif #ifndef configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS #warning "configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS is not defined. We recommend defining it to 0 in FreeRTOSConfig.h for better security." #define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1 #endif /* Constants required to access and manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SHPR2_REG ( *( ( volatile uint32_t * ) 0xe000ed1c ) ) #define portNVIC_SYS_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portNVIC_MEM_FAULT_ENABLE ( 1UL << 16UL ) /* Constants used to detect Cortex-M7 r0p0 and r0p1 cores, and ensure * that a work around is active for errata 837070. */ #define portCPUID ( *( ( volatile uint32_t * ) 0xE000ed00 ) ) #define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) #define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) /* Constants required to access and manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_REGION_BASE_ADDRESS_REG ( *( ( volatile uint32_t * ) 0xe000ed9C ) ) #define portMPU_REGION_ATTRIBUTE_REG ( *( ( volatile uint32_t * ) 0xe000edA0 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) #define portMPU_ENABLE ( 0x01UL ) #define portMPU_BACKGROUND_ENABLE ( 1UL << 2UL ) #define portPRIVILEGED_EXECUTION_START_ADDRESS ( 0UL ) #define portMPU_REGION_VALID ( 0x10UL ) #define portMPU_REGION_ENABLE ( 0x01UL ) #define portPERIPHERALS_START_ADDRESS 0x40000000UL #define portPERIPHERALS_END_ADDRESS 0x5FFFFFFFUL /* Constants required to access and manipulate the SysTick. */ #define portNVIC_SYSTICK_INT ( 0x00000002UL ) #define portNVIC_SYSTICK_ENABLE ( 0x00000001UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) #define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /* Constants required to manipulate the VFP. */ #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34UL ) /* Floating point context control register. */ #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000UL ) #define portINITIAL_EXC_RETURN ( 0xfffffffdUL ) #define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 ) #define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) #define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) ) #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) /* Offsets in the stack to the parameters when inside the SVC handler. */ #define portOFFSET_TO_PC ( 6 ) /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) /* * Configure a number of standard MPU regions that are used by all tasks. */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; /* * Return the smallest MPU region size that a given number of bytes will fit * into. The region size is returned as the value that should be programmed * into the region attribute register for that region. */ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) PRIVILEGED_FUNCTION; /* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ); /* * Standard FreeRTOS exception handlers. */ void xPortPendSVHandler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; void xPortSysTickHandler( void ) PRIVILEGED_FUNCTION; void vPortSVCHandler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /* * Starts the scheduler by restoring the context of the first task to run. */ static void prvRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /* * C portion of the SVC handler. The SVC handler is split between an asm entry * and a C wrapper for simplicity of coding and maintenance. */ static void prvSVCHandler( uint32_t * pulRegisters ) __attribute__( ( noinline ) ) PRIVILEGED_FUNCTION; /* * Function to enable the VFP. */ static void vPortEnableVFP( void ) __attribute__( ( naked ) ); /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Enter critical section. */ #if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL; #else void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; #endif /** * @brief Exit from critical section. */ #if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL; #else void vPortExitCritical( void ) PRIVILEGED_FUNCTION; #endif /*-----------------------------------------------------------*/ /* Each task maintains its own interrupt status in the critical nesting * variable. Note this is not saved as part of the task context as context * switches can only occur when uxCriticalNesting is zero. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. */ #if ( configASSERT_DEFINED == 1 ) static uint8_t ucMaxSysCallPriority = 0; static uint32_t ulMaxPRIGROUPValue = 0; static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ pxTopOfStack--; *pxTopOfStack = 0; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ /* A save method is being used that requires each task to maintain its * own exec return value. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack -= 9; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_IF_PRIVILEGED; } else { *pxTopOfStack = portINITIAL_CONTROL_IF_UNPRIVILEGED; } return pxTopOfStack; } /*-----------------------------------------------------------*/ void vPortSVCHandler( void ) { /* Assumes psp was in use. */ __asm volatile ( #ifndef USE_PROCESS_STACK /* Code should not be required if a main() is using the process stack. */ " tst lr, #4 \n" " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" #else " mrs r0, psp \n" #endif " b %0 \n" ::"i" ( prvSVCHandler ) : "r0", "memory" ); } /*-----------------------------------------------------------*/ static void prvSVCHandler( uint32_t * pulParam ) { uint8_t ucSVCNumber; uint32_t ulPC; #if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* #if defined( __ARMCC_VERSION ) */ #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ /* The stack contains: r0, r1, r2, r3, r12, LR, PC and xPSR. The first * argument (r0) is pulParam[ 0 ]. */ ulPC = pulParam[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { case portSVC_START_SCHEDULER: portNVIC_SHPR2_REG |= portNVIC_SVC_PRI; prvRestoreContextOfFirstTask(); break; case portSVC_YIELD: portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required * but do ensure the code is completely * within the specified behaviour for the * architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); break; #if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the * svc was raised from any of the * system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { __asm volatile ( " mrs r1, control \n"/* Obtain current control value. */ " bic r1, #1 \n"/* Set privilege bit. */ " msr control, r1 \n"/* Write back new control value. */ ::: "r1", "memory" ); } break; #else /* if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ case portSVC_RAISE_PRIVILEGE: __asm volatile ( " mrs r1, control \n"/* Obtain current control value. */ " bic r1, #1 \n"/* Set privilege bit. */ " msr control, r1 \n"/* Write back new control value. */ ::: "r1", "memory" ); break; #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ default: /* Unknown SVC call. */ break; } } /*-----------------------------------------------------------*/ static void prvRestoreContextOfFirstTask( void ) { __asm volatile ( " ldr r0, =0xE000ED08 \n"/* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" " ldr r0, [r0] \n" " msr msp, r0 \n"/* Set the msp back to the start of the stack. */ " ldr r3, pxCurrentTCBConst2 \n"/* Restore the context. */ " ldr r1, [r3] \n" " ldr r0, [r1] \n"/* The first item in the TCB is the task top of stack. */ " add r1, r1, #4 \n"/* Move onto the second item in the TCB... */ " \n" " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " bic r3, #1 \n"/* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ " str r3, [r2] \n"/* Disable MPU. */ " \n" " ldr r2, =0xe000ed9c \n"/* Region Base Address register. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */ " stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers [MPU Region # 4 - 7]. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */ " stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 12 - 15]. */ " stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers. [MPU Region # 12 - 15]. */ #endif /* configTOTAL_MPU_REGIONS == 16. */ " \n" " ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " orr r3, #1 \n"/* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ " str r3, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ " \n" " ldmia r0!, {r3-r11, r14} \n"/* Pop the registers that are not automatically saved on exception entry. */ " msr control, r3 \n" " msr psp, r0 \n"/* Restore the task stack pointer. */ " mov r0, #0 \n" " msr basepri, r0 \n" " bx r14 \n" " \n" " .ltorg \n"/* Assemble current literal pool to avoid offset-out-of-bound errors with lto. */ " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" ); } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); /* Errata 837070 workaround must only be enabled on Cortex-M7 r0p0 * and r0p1 cores. */ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) configASSERT( ( portCPUID == portCORTEX_M7_r0p1_ID ) || ( portCPUID == portCORTEX_M7_r0p0_ID ) ); #else /* When using this port on a Cortex-M7 r0p0 or r0p1 core, define * configENABLE_ERRATA_837070_WORKAROUND to 1 in your * FreeRTOSConfig.h. */ configASSERT( portCPUID != portCORTEX_M7_r0p1_ID ); configASSERT( portCPUID != portCORTEX_M7_r0p0_ID ); #endif #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API * functions can be called. ISR safe functions are those that end in * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { ulMaxPRIGROUPValue--; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); } #endif /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; /* Restore the clobbered interrupt priority register to its original * value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* Make PendSV and SysTick the same priority as the kernel, and the SVC * handler higher priority so it can be used to exit a critical section (where * lower priorities are masked). */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Configure the regions in the MPU that are common to all tasks. */ prvSetupMPU(); /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Ensure the VFP is enabled - it should be anyway. */ vPortEnableVFP(); /* Lazy save always. */ *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; /* Start the first task. This also clears the bit that indicates the FPU is * in use in case the FPU was used before the scheduler was started - which * would otherwise result in the unnecessary leaving of space in the SVC stack * for lazy saving of FPU registers. */ __asm volatile ( " ldr r0, =0xE000ED08 \n"/* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" " ldr r0, [r0] \n" " msr msp, r0 \n"/* Set the msp back to the start of the stack. */ " mov r0, #0 \n"/* Clear the bit that indicates the FPU is in use, see comment above. */ " msr control, r0 \n" " cpsie i \n"/* Globally enable interrupts. */ " cpsie f \n" " dsb \n" " isb \n" " svc %0 \n"/* System call to start first task. */ " nop \n" " .ltorg \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { #if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); portDISABLE_INTERRUPTS(); uxCriticalNesting++; portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { portDISABLE_INTERRUPTS(); uxCriticalNesting++; } #else portDISABLE_INTERRUPTS(); uxCriticalNesting++; #endif } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { #if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } #else configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } #endif } /*-----------------------------------------------------------*/ void xPortPendSVHandler( void ) { /* This is a naked function. */ __asm volatile ( " mrs r0, psp \n" " isb \n" " \n" " ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */ " ldr r2, [r3] \n" " \n" " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, push high vfp registers. */ " it eq \n" " vstmdbeq r0!, {s16-s31} \n" " \n" " mrs r1, control \n" " stmdb r0!, {r1, r4-r11, r14} \n"/* Save the remaining registers. */ " str r0, [r2] \n"/* Save the new top of stack into the first member of the TCB. */ " \n" " stmdb sp!, {r0, r3} \n" " mov r0, %0 \n" #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) " cpsid i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ #endif " msr basepri, r0 \n" " dsb \n" " isb \n" #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) " cpsie i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ #endif " bl vTaskSwitchContext \n" " mov r0, #0 \n" " msr basepri, r0 \n" " ldmia sp!, {r0, r3} \n" " \n"/* Restore the context. */ " ldr r1, [r3] \n" " ldr r0, [r1] \n"/* The first item in the TCB is the task top of stack. */ " add r1, r1, #4 \n"/* Move onto the second item in the TCB... */ " \n" " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " bic r3, #1 \n"/* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ " str r3, [r2] \n"/* Disable MPU. */ " \n" " ldr r2, =0xe000ed9c \n"/* Region Base Address register. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */ " stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers [MPU Region # 4 - 7]. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */ " stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 12 - 15]. */ " stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers. [MPU Region # 12 - 15]. */ #endif /* configTOTAL_MPU_REGIONS == 16. */ " \n" " ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " orr r3, #1 \n"/* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ " str r3, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ " \n" " ldmia r0!, {r3-r11, r14} \n"/* Pop the registers that are not automatically saved on exception entry. */ " msr control, r3 \n" " \n" " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, pop the high vfp registers too. */ " it eq \n" " vldmiaeq r0!, {s16-s31} \n" " \n" " msr psp, r0 \n" " bx r14 \n" " \n" " .ltorg \n"/* Assemble the current literal pool to avoid offset-out-of-bound errors with lto. */ " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { uint32_t ulDummy; ulDummy = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy ); } /*-----------------------------------------------------------*/ /* * Setup the systick timer to generate the tick interrupts at the required * frequency. */ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) { /* Stop and clear the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE ); } /*-----------------------------------------------------------*/ /* This is a naked function. */ static void vPortEnableVFP( void ) { __asm volatile ( " ldr.w r0, =0xE000ED88 \n"/* The FPU enable bits are in the CPACR. */ " ldr r1, [r0] \n" " \n" " orr r1, r1, #( 0xf << 20 ) \n"/* Enable CP10 and CP11 coprocessors, then save back. */ " str r1, [r0] \n" " bx r14 \n" " .ltorg \n" ); } /*-----------------------------------------------------------*/ static void prvSetupMPU( void ) { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __FLASH_segment_start__; extern uint32_t * __FLASH_segment_end__; extern uint32_t * __privileged_data_start__; extern uint32_t * __privileged_data_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __FLASH_segment_start__[]; extern uint32_t __FLASH_segment_end__[]; extern uint32_t __privileged_data_start__[]; extern uint32_t __privileged_data_end__[]; #endif /* if defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check the expected MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* First setup the unprivileged flash for unprivileged read only access. */ portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __FLASH_segment_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | ( portUNPRIVILEGED_FLASH_REGION ); portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_READ_ONLY ) | ( ( configTEX_S_C_B_FLASH & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( prvGetMPURegionSizeSetting( ( uint32_t ) __FLASH_segment_end__ - ( uint32_t ) __FLASH_segment_start__ ) ) | ( portMPU_REGION_ENABLE ); /* Setup the privileged flash for privileged only access. This is where * the kernel code is placed. */ portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_functions_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | ( portPRIVILEGED_FLASH_REGION ); portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_PRIVILEGED_READ_ONLY ) | ( ( configTEX_S_C_B_FLASH & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_functions_end__ - ( uint32_t ) __privileged_functions_start__ ) ) | ( portMPU_REGION_ENABLE ); /* Setup the privileged data RAM region. This is where the kernel data * is placed. */ portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | ( portPRIVILEGED_RAM_REGION ); portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ) | ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_data_end__ - ( uint32_t ) __privileged_data_start__ ) | ( portMPU_REGION_ENABLE ); /* By default allow everything to access the general peripherals. The * system peripherals and registers are protected. */ portMPU_REGION_BASE_ADDRESS_REG = ( portPERIPHERALS_START_ADDRESS ) | ( portMPU_REGION_VALID ) | ( portGENERAL_PERIPHERALS_REGION ); portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_READ_WRITE | portMPU_REGION_EXECUTE_NEVER ) | ( prvGetMPURegionSizeSetting( portPERIPHERALS_END_ADDRESS - portPERIPHERALS_START_ADDRESS ) ) | ( portMPU_REGION_ENABLE ); /* Enable the memory fault exception. */ portNVIC_SYS_CTRL_STATE_REG |= portNVIC_MEM_FAULT_ENABLE; /* Enable the MPU with the background region configured. */ portMPU_CTRL_REG |= ( portMPU_ENABLE | portMPU_BACKGROUND_ENABLE ); } } /*-----------------------------------------------------------*/ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) { uint32_t ulRegionSize, ulReturnValue = 4; /* 32 is the smallest region size, 31 is the largest valid value for * ulReturnValue. */ for( ulRegionSize = 32UL; ulReturnValue < 31UL; ( ulRegionSize <<= 1UL ) ) { if( ulActualSizeInBytes <= ulRegionSize ) { break; } else { ulReturnValue++; } } /* Shift the code by one before returning so it can be written directly * into the the correct bit position of the attribute register. */ return( ulReturnValue << 1UL ); } /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " mrs r0, control \n"/* r0 = CONTROL. */ " tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ " ite ne \n" " 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. */ " bx lr \n"/* Return. */ " \n" " .align 4 \n" ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vResetPrivilege( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " mrs r0, control \n"/* r0 = CONTROL. */ " orr r0, #1 \n"/* r0 = r0 | 1. */ " msr control, r0 \n"/* CONTROL = r0. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __SRAM_segment_start__; extern uint32_t * __SRAM_segment_end__; extern uint32_t * __privileged_data_start__; extern uint32_t * __privileged_data_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __SRAM_segment_start__[]; extern uint32_t __SRAM_segment_end__[]; extern uint32_t __privileged_data_start__[]; extern uint32_t __privileged_data_end__[]; #endif /* if defined( __ARMCC_VERSION ) */ int32_t lIndex; uint32_t ul; if( xRegions == NULL ) { /* No MPU regions are specified so allow access to all RAM. */ xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = ( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | ( portSTACK_REGION ); /* Region number. */ xMPUSettings->xRegion[ 0 ].ulRegionAttribute = ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ) | ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( prvGetMPURegionSizeSetting( ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__ ) ) | ( portMPU_REGION_ENABLE ); /* Invalidate user configurable regions. */ for( ul = 1UL; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) { xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID ); xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; } } else { /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that the * stack region has already been configured. */ if( ulStackDepth > 0 ) { /* Define the region that allows access to the stack. */ xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = ( ( uint32_t ) pxBottomOfStack ) | ( portMPU_REGION_VALID ) | ( portSTACK_REGION ); /* Region number. */ xMPUSettings->xRegion[ 0 ].ulRegionAttribute = ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ) | ( prvGetMPURegionSizeSetting( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) ) | ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( portMPU_REGION_ENABLE ); } lIndex = 0; for( ul = 1UL; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) { if( ( xRegions[ lIndex ] ).ulLengthInBytes > 0UL ) { /* Translate the generic region definition contained in * xRegions into the CM4 specific MPU settings that are then * stored in xMPUSettings. */ xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) | ( portMPU_REGION_VALID ) | ( ul - 1UL ); /* Region number. */ xMPUSettings->xRegion[ ul ].ulRegionAttribute = ( prvGetMPURegionSizeSetting( xRegions[ lIndex ].ulLengthInBytes ) ) | ( xRegions[ lIndex ].ulParameters ) | ( portMPU_REGION_ENABLE ); } else { /* Invalidate the region. */ xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID ); xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; } lIndex++; } } } /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); /* Is the interrupt number a user defined interrupt? */ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /* Look up the interrupt's priority. */ ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Interrupts that use the FreeRTOS API must not be left at their * default priority of zero as that is the highest possible priority, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * and therefore also guaranteed to be invalid. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } /* Priority grouping: The interrupt controller (NVIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined * to be pre-emption priority bits. The following assertion will fail if * this is not the case (if some bits represent a sub-priority). * * If the application only uses CMSIS libraries for interrupt * configuration then the correct setting can be achieved on all Cortex-M * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * scheduler. Note however that some vendor specific peripheral libraries * assume a non-zero priority group setting, in which cases using a value * of zero will result in unpredicable behaviour. */ configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); } #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM4_MPU/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* MPU specific constants. */ #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #define portMPU_REGION_READ_WRITE ( 0x03UL << 24UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 0x05UL << 24UL ) #define portMPU_REGION_READ_ONLY ( 0x06UL << 24UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0x01UL << 24UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ( 0x02UL << 24UL ) #define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL ) #define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL ) /* Location of the TEX,S,C,B bits in the MPU Region Attribute and Size * Register (RASR). */ #define portMPU_RASR_TEX_S_C_B_LOCATION ( 16UL ) #define portMPU_RASR_TEX_S_C_B_MASK ( 0x3FUL ) /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* * The TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits define the * memory type, and where necessary the cacheable and shareable properties * of the memory region. * * The TEX, C, and B bits together indicate the memory type of the region, * and: * - For Normal memory, the cacheable properties of the region. * - For Device memory, whether the region is shareable. * * For Normal memory regions, the S bit indicates whether the region is * shareable. For Strongly-ordered and Device memory, the S bit is ignored. * * See the following two tables for setting TEX, S, C and B bits for * unprivileged flash, privileged flash and privileged RAM regions. * +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | TEX | C | B | Memory type | Description or Normal region cacheability | Shareable? | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 000 | 0 | 0 | Strongly-ordered | Strongly ordered | Shareable | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 000 | 0 | 1 | Device | Shared device | Shareable | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 000 | 1 | 0 | Normal | Outer and inner write-through; no write allocate | S bit | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 000 | 1 | 1 | Normal | Outer and inner write-back; no write allocate | S bit | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 001 | 0 | 0 | Normal | Outer and inner Non-cacheable | S bit | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 001 | 0 | 1 | Reserved | Reserved | Reserved | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 001 | 1 | 0 | IMPLEMENTATION DEFINED | IMPLEMENTATION DEFINED | IMPLEMENTATION DEFINED | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 001 | 1 | 1 | Normal | Outer and inner write-back; write and read allocate | S bit | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 010 | 0 | 0 | Device | Non-shared device | Not shareable | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 010 | 0 | 1 | Reserved | Reserved | Reserved | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 010 | 1 | X | Reserved | Reserved | Reserved | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 011 | X | X | Reserved | Reserved | Reserved | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 1BB | A | A | Normal | Cached memory, with AA and BB indicating the inner and | Reserved | | | | | | outer cacheability rules that must be exported on the | | | | | | | bus. See the table below for the cacheability policy | | | | | | | encoding. memory, BB=Outer policy, AA=Inner policy. | | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | +-----------------------------------------+----------------------------------------+ | AA or BB subfield of {TEX,C,B} encoding | Cacheability policy | +-----------------------------------------+----------------------------------------+ | 00 | Non-cacheable | +-----------------------------------------+----------------------------------------+ | 01 | Write-back, write and read allocate | +-----------------------------------------+----------------------------------------+ | 10 | Write-through, no write allocate | +-----------------------------------------+----------------------------------------+ | 11 | Write-back, no write allocate | +-----------------------------------------+----------------------------------------+ */ /* TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits for flash * region. */ #ifndef configTEX_S_C_B_FLASH /* Default to TEX=000, S=1, C=1, B=1 for backward compatibility. */ #define configTEX_S_C_B_FLASH ( 0x07UL ) #endif /* TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits for RAM * region. */ #ifndef configTEX_S_C_B_SRAM /* Default to TEX=000, S=1, C=1, B=1 for backward compatibility. */ #define configTEX_S_C_B_SRAM ( 0x07UL ) #endif #define portGENERAL_PERIPHERALS_REGION ( configTOTAL_MPU_REGIONS - 5UL ) #define portSTACK_REGION ( configTOTAL_MPU_REGIONS - 4UL ) #define portUNPRIVILEGED_FLASH_REGION ( configTOTAL_MPU_REGIONS - 3UL ) #define portPRIVILEGED_FLASH_REGION ( configTOTAL_MPU_REGIONS - 2UL ) #define portPRIVILEGED_RAM_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portFIRST_CONFIGURABLE_REGION ( 0UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 6UL ) #define portNUM_CONFIGURABLE_REGIONS ( configTOTAL_MPU_REGIONS - 5UL ) #define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus 1 to create space for the stack region. */ #define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " ::: "r0", "memory" ) typedef struct MPU_REGION_REGISTERS { uint32_t ulRegionBaseAddress; uint32_t ulRegionAttribute; } xMPU_REGION_REGISTERS; typedef struct MPU_SETTINGS { xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ]; } xMPU_SETTINGS; /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ /* SVC numbers for various services. */ #define portSVC_START_SCHEDULER 0 #define portSVC_YIELD 1 #define portSVC_RAISE_PRIVILEGE 2 /* Scheduler utilities. */ #define portYIELD() __asm volatile ( " SVC %0 \n"::"i" ( portSVC_YIELD ) : "memory" ) #define portYIELD_WITHIN_API() \ { \ /* Set a PendSV to request a context switch. */ \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ \ /* Barriers are normally not required but do ensure the code is completely \ * within the specified behaviour for the architecture. */ \ __asm volatile ( "dsb" ::: "memory" ); \ __asm volatile ( "isb" ); \ } #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x ) #define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() #define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /* 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 * (which build with all the ports) will build. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Generic helper function. */ __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) { uint8_t ucReturn; __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" ); return ucReturn; } /* Check the configuration. */ #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. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /*-----------------------------------------------------------*/ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* portNOP() is not required by this port. */ #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif /*-----------------------------------------------------------*/ extern BaseType_t xIsPrivileged( void ); extern void vResetPrivilege( void ); /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() /*-----------------------------------------------------------*/ portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ portFORCE_INLINE static void vPortRaiseBASEPRI( void ) { uint32_t ulNewBASEPRI; __asm volatile ( " mov %0, %1 \n" #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) " cpsid i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ #endif " msr basepri, %0 \n" " isb \n" " dsb \n" #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) " cpsie i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ #endif : "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); } /*-----------------------------------------------------------*/ portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) { uint32_t ulOriginalBASEPRI, ulNewBASEPRI; __asm volatile ( " mrs %0, basepri \n" " mov %1, %2 \n" #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) " cpsid i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ #endif " msr basepri, %1 \n" " isb \n" " dsb \n" #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) " cpsie i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ #endif : "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); /* This return will not be reached but is necessary to prevent compiler * warnings. */ return ulOriginalBASEPRI; } /*-----------------------------------------------------------*/ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) { __asm volatile ( " msr basepri, %0 "::"r" ( ulNewMaskValue ) : "memory" ); } /*-----------------------------------------------------------*/ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #ifndef configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY #warning "configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY is not defined. We recommend defining it to 1 in FreeRTOSConfig.h for better security. https://www.FreeRTOS.org/FreeRTOS-V10.3.x.html" #define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 0 #endif /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55/non_secure/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /* Portasm includes. */ #include "portasm.h" #if ( configENABLE_TRUSTZONE == 1 ) /* Secure components includes. */ #include "secure_context.h" #include "secure_init.h" #endif /* configENABLE_TRUSTZONE */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /** * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS * on the secure side. The following are the valid configuration seetings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 * * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 * * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 */ #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. #endif /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the SCB. */ #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the FPU. */ #define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) #define portMPU_RLAR_REGION_ENABLE ( 1UL ) /* Enable privileged access to unmapped region. */ #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /*-----------------------------------------------------------*/ /** * @brief The maximum 24-bit number. * * It is needed because the systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /** * @brief A fiddle factor to estimate the number of SysTick counts that would * have occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) /** * @brief Initial EXC_RETURN value. * * FF FF FF FD * 1111 1111 1111 1111 1111 1111 1111 1101 * * Bit[6] - 1 --> The exception was taken from the Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 1 --> The exception was taken to the Secure state. */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else /** * @brief Initial EXC_RETURN value. * * FF FF FF BC * 1111 1111 1111 1111 1111 1111 1011 1100 * * Bit[6] - 0 --> The exception was taken from the Non-Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 0 --> The exception was taken to the Non-Secure state. */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ /** * @brief CONTROL register privileged bit mask. * * Bit[0] in CONTROL register tells the privilege: * Bit[0] = 0 ==> The task is privileged. * Bit[0] = 1 ==> The task is not privileged. */ #define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) /** * @brief Initial CONTROL register values. */ #define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) #define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) /** * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /** * @brief 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /** * @brief If portPRELOAD_REGISTERS then registers will be given an initial value * when a task is created. This helps in debugging at the cost of code size. */ #define portPRELOAD_REGISTERS 1 /** * @brief A task is created without a secure context, and must call * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes * any secure calls. */ #define portNO_SECURE_CONTEXT 0 /*-----------------------------------------------------------*/ /** * @brief Used to catch tasks that attempt to return from their implementing * function. */ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) /** * @brief Setup the Memory Protection Unit (MPU). */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) /** * @brief Setup the Floating Point Unit (FPU). */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ /** * @brief Setup the timer to generate the tick interrupts. * * The implementation in this file is weak to allow application writers to * change the timer used to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /** * @brief Checks whether the current execution context is interrupt. * * @return pdTRUE if the current execution context is interrupt, pdFALSE * otherwise. */ BaseType_t xPortIsInsideInterrupt( void ); /** * @brief Yield the processor. */ void vPortYield( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ void vPortExitCritical( void ) PRIVILEGED_FUNCTION; /** * @brief SysTick handler. */ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; /** * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. */ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Saved as part of the task context to indicate which context the * task is using on the secure side. */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ #if ( configUSE_TICKLESS_IDLE == 1 ) /** * @brief The number of SysTick increments that make up one tick period. */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; /** * @brief The maximum number of tick periods that can be suppressed is * limited by the 24 bit resolution of the SysTick timer. */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; /** * @brief Compensate for the CPU cycles that pass while the SysTick is * stopped (low power functionality only). */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). Artificially force an assert() * to be triggered if configASSERT() is defined, then stop here so * application writers can catch the error. */ configASSERT( ulCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being * defined but never called. ulDummy is used purely to quieten other * warnings about code appearing after this function is called - making * ulDummy volatile makes the compiler think the function could return * and therefore not output an 'unreachable code' warning for code that * appears after it. */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; extern uint32_t * __unprivileged_flash_start__; extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* if defined( __ARMCC_VERSION ) */ /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; extern uint32_t __unprivileged_flash_start__[]; extern uint32_t __unprivileged_flash_end__[]; extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check that the MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* MAIR0 - Index 0. */ portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); /* MAIR0 - Index 1. */ portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* Setup privileged flash as Read Only so that privileged tasks can * read it but not modify. */ portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged flash as Read Only by both privileged and * unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged syscalls flash as Read Only by both privileged * and unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup RAM containing kernel data for privileged access only. */ portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Enable mem fault. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; /* Enable MPU with privileged background access i.e. unmapped * regions have privileged access. */ portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) { /* Enable non-secure access to the FPU. */ SecureInit_EnableNSFPUAccess(); } #endif /* configENABLE_TRUSTZONE */ /* CP10 = 11 ==> Full access to FPU i.e. both privileged and * unprivileged code should be able to access FPU. CP11 should be * programmed to the same value as CP10. */ *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) ); /* ASPEN = 1 ==> Hardware should automatically preserve floating point * context on exception entry and restore on exception return. * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ void vPortYield( void ) /* PRIVILEGED_FUNCTION */ { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ { portDISABLE_INTERRUPTS(); ulCriticalNesting++; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ { configASSERT( ulCriticalNesting ); ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { #if ( configENABLE_MPU == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ #endif /* configENABLE_MPU */ uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) uint32_t ulR0, ulR1; extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ #endif /* configENABLE_TRUSTZONE */ uint8_t ucSVCNumber; /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ ulPC = pulCallerStackAddress[ 6 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { #if ( configENABLE_TRUSTZONE == 1 ) case portSVC_ALLOCATE_SECURE_CONTEXT: /* R0 contains the stack size passed as parameter to the * vPortAllocateSecureContext function. */ ulR0 = pulCallerStackAddress[ 0 ]; #if ( configENABLE_MPU == 1 ) { /* Read the CONTROL register value. */ __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); /* The task that raised the SVC is privileged if Bit[0] * in the CONTROL register is 0. */ ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: /* R0 contains TCB being freed and R1 contains the secure * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) { /* De-prioritize the non-secure exceptions so that the * non-secure pendSV runs at the lowest priority. */ SecureInit_DePrioritizeNSExceptions(); /* Initialize the secure context management system. */ SecureContext_Init(); } #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_FPU == 1 ) { /* Setup the Floating Point Unit (FPU). */ prvSetupFPU(); } #endif /* configENABLE_FPU */ /* Setup the context of the first task so that the first task starts * executing. */ vRestoreContextOfFirstTask(); break; #if ( configENABLE_MPU == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the svc was raised from any of * the system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { vRaisePrivilege(); } break; #endif /* configENABLE_MPU */ default: /* Incorrect SVC call. */ configASSERT( pdFALSE ); } } /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #if ( configENABLE_MPU == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /* *INDENT-ON* */ { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #endif /* portPRELOAD_REGISTERS */ return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ prvSetupMPU(); } #endif /* configENABLE_MPU */ /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; /* Start the first task. */ vStartFirstTask(); /* Should never get here as the tasks will now be executing. Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* Setup MAIR0. */ xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ if( ulStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged * SRAM is already protected using an MPU region and ARMv8-M does * not allow overlapping MPU regions. */ if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) { xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; } else { /* Define the region that allows access to the stack. */ ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); } } /* User supplied configurable regions. */ for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) { /* If xRegions is NULL i.e. the task has not specified any MPU * region, the else part ensures that all the configurable MPU * regions are invalidated. */ if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) { /* Translate the generic region definition contained in xRegions * into the ARMv8 specific MPU settings that are then stored in * xMPUSettings. */ ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; /* Start address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ); /* RO/RW. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); } else { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); } /* XN. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); } /* End Address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { /* Attr1 in MAIR0 is configured as device memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; } else { /* Attr0 in MAIR0 is configured as normal memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; } } else { /* Invalidate the region. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; } lIndex++; } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. Interrupt Program * Status Register (IPSR) holds the exception number of the currently-executing * exception or zero for Thread mode.*/ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55/non_secure/portasm.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION * is defined correctly and privileged functions are placed in correct sections. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Portasm includes. */ #include "portasm.h" /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r4, [r2] \n"/* Disable MPU. */ " \n" " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r4, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r4, #4 \n"/* r4 = 4. */ " str r4, [r2] \n"/* Program RNR = 4. */ " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r3!, {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. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r4, #8 \n"/* r4 = 8. */ " str r4, [r2] \n"/* Program RNR = 8. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r3!, {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. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r4, #12 \n"/* r4 = 12. */ " str r4, [r2] \n"/* Program RNR = 12. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r3!, {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. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " str r4, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ " ldr r5, xSecureContextConst2 \n" " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ " msr control, r3 \n"/* Set this task's CONTROL value. */ " 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. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " bx r4 \n"/* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, xSecureContextConst2 \n" " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ " movs r1, #2 \n"/* r1 = 2. */ " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ " 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. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " bx r3 \n"/* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" "xSecureContextConst2: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst2: .word 0xe000ed94 \n" "xMAIR0Const2: .word 0xe000edc0 \n" "xRNRConst2: .word 0xe000ed98 \n" "xRBARConst2: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ " ite ne \n" " 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. */ " bx lr \n"/* Return. */ " \n" " .align 4 \n" ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* Read the CONTROL register. */ " bic r0, #1 \n"/* Clear the bit 0. */ " msr control, r0 \n"/* Write back the new CONTROL value. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vResetPrivilege( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " orr r0, #1 \n"/* r0 = r0 | 1. */ " msr control, r0 \n"/* CONTROL = r0. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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"/* The first entry in vector table is stack pointer. */ " msr msp, r0 \n"/* Set the MSP back to the start of the stack. */ " cpsie i \n"/* Globally enable interrupts. */ " cpsie f \n" " dsb \n" " isb \n" " svc %0 \n"/* System call to start the first task. */ " nop \n" " \n" " .align 4 \n" "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } /*-----------------------------------------------------------*/ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n"/* Return. */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); } /*-----------------------------------------------------------*/ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " msr basepri, r0 \n"/* basepri = ulMask. */ " dsb \n" " isb \n" " bx lr \n"/* Return. */ ::: "memory" ); } /*-----------------------------------------------------------*/ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" " 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 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. */ " mrs r2, psp \n"/* Read PSP in r2. */ " \n" " cbz r0, save_ns_context \n"/* No secure context to save. */ " push {r0-r2, r14} \n" " bl SecureContext_SaveContext \n"/* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r0-r3} \n"/* LR is now in 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. */ " 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" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB.*/ #if ( configENABLE_MPU == 1 ) " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ " str r2, [r1] \n"/* Save the new top of stack in TCB. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r3, control \n"/* r3 = CONTROL. */ " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ " 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. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ " b select_next_task \n" " \n" " save_ns_context: \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ #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. */ " it eq \n" " vstmdbeq r2!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ " str r2, [r1] \n"/* Save the new top of stack in TCB. */ " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r3, control \n"/* r3 = CONTROL. */ " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ " subs r2, r2, #16 \n"/* r2 = r2 - 16. */ " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ " 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. */ " adds r2, r2, #12 \n"/* r2 = r2 + 12. */ " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " subs r2, r2, #12 \n"/* r2 = r2 - 12. */ " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ " \n" " select_next_task: \n" " mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" " mov r0, #0 \n"/* r0 = 0. */ " msr basepri, r0 \n"/* Enable interrupts. */ " \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r4, [r3] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ " str r4, [r3] \n"/* Program MAIR0. */ " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ " movs r4, #4 \n"/* r4 = 4. */ " str r4, [r3] \n"/* Program RNR = 4. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ " movs r4, #8 \n"/* r4 = 8. */ " str r4, [r3] \n"/* Program RNR = 8. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ " movs r4, #12 \n"/* r4 = 12. */ " str r4, [r3] \n"/* Program RNR = 12. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " str r4, [r3] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ " mov lr, r4 \n"/* LR = r4. */ " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( 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. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " push {r2, r4} \n" " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r2, r4} \n" " 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. */ " 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. */ " bx lr \n" #else /* configENABLE_MPU */ " 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. */ " mov lr, r4 \n"/* LR = r4. */ " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( 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. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " push {r2, r4} \n" " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r2, r4} \n" " 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. */ " 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. */ " bx lr \n" #endif /* configENABLE_MPU */ " \n" " restore_ns_context: \n" " ldmia r2!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */ #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. */ " it eq \n" " vldmiaeq r2!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ " msr psp, r2 \n"/* Remember the new top of stack for the task. */ " bx lr \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" "xSecureContextConst: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst: .word 0xe000ed94 \n" "xMAIR0Const: .word 0xe000edc0 \n" "xRNRConst: .word 0xe000ed98 \n" "xRBARConst: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } /*-----------------------------------------------------------*/ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " tst lr, #4 \n" " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" " ldr r1, svchandler_address_const \n" " bx r1 \n" " \n" " .align 4 \n" "svchandler_address_const: .word vPortSVCHandler_C \n" ); } /*-----------------------------------------------------------*/ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " svc %0 \n"/* Secure context is allocated in the supervisor call. */ " bx lr \n"/* Return. */ ::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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. */ " cmp r1, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */ " it ne \n" " svcne %0 \n"/* Secure context is freed in the supervisor call. */ " bx lr \n"/* Return. */ ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55/non_secure/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORT_ASM_H__ #define __PORT_ASM_H__ /* Scheduler includes. */ #include "FreeRTOS.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /** * @brief Restore the context of the first task so that the first task starts * executing. */ void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * * @note This is a privileged function and should only be called from the kenrel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Starts the first task. */ void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Disables interrupts. */ uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Enables interrupts. */ void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief PendSV Exception handler. */ void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief SVC Handler. */ void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Allocate a Secure context for the calling task. * * @param[in] ulSecureStackSize The size of the stack to be allocated on the * secure side for the calling task. */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); /** * @brief Free the task's secure context. * * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. */ void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* __PORT_ASM_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55/non_secure/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_MVE #error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE. #endif /* configENABLE_MVE */ /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M55" #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACROCOMMON_H #define PORTMACROCOMMON_H #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_FPU #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. #endif /* configENABLE_FPU */ #ifndef configENABLE_MPU #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. #endif /* configENABLE_MPU */ #ifndef configENABLE_TRUSTZONE #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ /** * @brief Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif #define portHAS_STACK_OVERFLOW_CHECKING 1 /*-----------------------------------------------------------*/ /** * @brief Extern declarations. */ extern BaseType_t xPortIsInsideInterrupt( void ); extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; #if ( configENABLE_TRUSTZONE == 1 ) extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_MPU == 1 ) extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief MPU specific constants. */ #if ( configENABLE_MPU == 1 ) #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #else #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* MPU regions. */ #define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_RAM_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ /* Device memory attributes used in MPU_MAIR registers. * * 8-bit values encoded as follows: * Bit[7:4] - 0000 - Device Memory * Bit[3:2] - 00 --> Device-nGnRnE * 01 --> Device-nGnRE * 10 --> Device-nGRE * 11 --> Device-GRE * Bit[1:0] - 00, Reserved. */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ /* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ /* Attributes used in MPU_RBAR registers. */ #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ /** * @brief Settings to define an MPU region. */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */ } MPURegionSettings_t; /** * @brief MPU settings as stored in the TCB. */ typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ } xMPU_SETTINGS; /*-----------------------------------------------------------*/ /** * @brief SVC numbers. */ #define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 /*-----------------------------------------------------------*/ /** * @brief Scheduler utilities. */ #define portYIELD() vPortYield() #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /** * @brief Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /** * @brief Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Allocate a secure context for the task. * * 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 context before it calls any secure function. * * @param[in] ulSecureStackSize The size of the secure stack to be allocated. */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) /** * @brief Called when a task is deleted to delete the task's secure context, * if it has one. * * @param[in] pxTCB The TCB of the task being deleted. */ #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. * * 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, * the privilege is not raised. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() #else #define portIS_PRIVILEGED() #define portRAISE_PRIVILEGE() #define portRESET_PRIVILEGE() #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief Barriers. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACROCOMMON_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55/secure/secure_context.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Secure context includes. */ #include "secure_context.h" /* Secure heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief CONTROL value for privileged tasks. * * Bit[0] - 0 --> Thread mode is privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_PRIVILEGED 0x02 /** * @brief CONTROL value for un-privileged tasks. * * Bit[0] - 1 --> Thread mode is un-privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 /** * @brief Size of stack seal values in bytes. */ #define securecontextSTACK_SEAL_SIZE 8 /** * @brief Stack seal value as recommended by ARM. */ #define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5 /** * @brief Maximum number of secure contexts. */ #ifndef secureconfigMAX_SECURE_CONTEXTS #define secureconfigMAX_SECURE_CONTEXTS 8UL #endif /*-----------------------------------------------------------*/ /** * @brief Pre-allocated array of secure contexts. */ SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ]; /*-----------------------------------------------------------*/ /** * @brief Get a free secure context for a task from the secure context pool (xSecureContexts). * * This function ensures that only one secure context is allocated for a task. * * @param[in] pvTaskHandle The task handle for which the secure context is allocated. * * @return Index of a free secure context in the xSecureContexts array. */ static uint32_t ulGetSecureContext( void * pvTaskHandle ); /** * @brief Return the secure context to the secure context pool (xSecureContexts). * * @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array. */ static void vReturnSecureContext( uint32_t ulSecureContextIndex ); /* These are implemented in assembly. */ extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ); extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ); /*-----------------------------------------------------------*/ static uint32_t ulGetSecureContext( void * pvTaskHandle ) { /* Start with invalid index. */ uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) && ( xSecureContexts[ i ].pucStackLimit == NULL ) && ( xSecureContexts[ i ].pucStackStart == NULL ) && ( xSecureContexts[ i ].pvTaskHandle == NULL ) && ( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = i; } else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle ) { /* A task can only have one secure context. Do not allocate a second * context for the same task. */ ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; break; } } return ulSecureContextIndex; } /*-----------------------------------------------------------*/ static void vReturnSecureContext( uint32_t ulSecureContextIndex ) { xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) { uint32_t ulIPSR, i; static uint32_t ulSecureContextsInitialized = 0; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) ) { /* Ensure to initialize secure contexts only once. */ ulSecureContextsInitialized = 1; /* No stack for thread mode until a task's context is loaded. */ secureportSET_PSPLIM( securecontextNO_STACK ); secureportSET_PSP( securecontextNO_STACK ); /* Initialize all secure contexts. */ for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { xSecureContexts[ i ].pucCurrentStackPointer = NULL; xSecureContexts[ i ].pucStackLimit = NULL; xSecureContexts[ i ].pucStackStart = NULL; xSecureContexts[ i ].pvTaskHandle = NULL; } #if ( configENABLE_MPU == 1 ) { /* Configure thread mode to use PSP and to be unprivileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED ); } #else /* configENABLE_MPU */ { /* Configure thread mode to use PSP and to be privileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED ); } #endif /* configENABLE_MPU */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ) #else /* configENABLE_MPU */ secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ) #endif /* configENABLE_MPU */ { uint8_t * pucStackMemory = NULL; uint8_t * pucStackLimit; uint32_t ulIPSR, ulSecureContextIndex; SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID; #if ( configENABLE_MPU == 1 ) uint32_t * pulCurrentStackPointer = NULL; #endif /* configENABLE_MPU */ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit * Register (PSPLIM) value. */ secureportREAD_IPSR( ulIPSR ); secureportREAD_PSPLIM( pucStackLimit ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. * Also do nothing, if a secure context us already loaded. PSPLIM is set to * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { /* Ontain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space. */ pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE ); if( pucStackMemory != NULL ) { /* Since stack grows down, the starting point will be the last * location. Note that this location is next to the last * allocated byte for stack (excluding the space for seal values) * because the hardware decrements the stack pointer before * writing i.e. if stack pointer is 0x2, a push operation will * decrement the stack pointer to 0x1 and then write at 0x1. */ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize; /* Seal the created secure process stack. */ *( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE; *( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE; /* The stack cannot go beyond this location. This value is * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle; #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 ) { *( 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 /* configENABLE_MPU */ { /* Current SP is set to the starting of the stack. This * value programmed in the PSP register on context switch. */ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart; } #endif /* configENABLE_MPU */ /* Ensure to never return 0 as a valid context handle. */ xSecureContextHandle = ulSecureContextIndex + 1UL; } } } return xSecureContextHandle; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint32_t ulIPSR, ulSecureContextIndex; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* Only free if a valid context handle is passed. */ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; /* Ensure that the secure context being deleted is associated with * the task. */ if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) { /* Free the stack space. */ vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); /* Return the secure context back to the free secure contexts pool. */ vReturnSecureContext( ulSecureContextIndex ); } } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that no secure context is loaded and the task is loading it's * own context. */ if( ( pucStackLimit == securecontextNO_STACK ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that task's context is loaded and the task is saving it's own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55/secure/secure_context.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_CONTEXT_H__ #define __SECURE_CONTEXT_H__ /* Standard includes. */ #include /* FreeRTOS includes. */ #include "FreeRTOSConfig.h" /** * @brief PSP value when no secure context is loaded. */ #define securecontextNO_STACK 0x0 /** * @brief Invalid context ID. */ #define securecontextINVALID_CONTEXT_ID 0UL /*-----------------------------------------------------------*/ /** * @brief Structure to represent a secure context. * * @note Since stack grows down, pucStackStart is the highest address while * pucStackLimit is the first address of the allocated memory. */ typedef struct SecureContext { uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */ uint8_t * pucStackStart; /**< First location of the stack memory. */ void * pvTaskHandle; /**< Task handle of the task this context is associated with. */ } SecureContext_t; /*-----------------------------------------------------------*/ /** * @brief Opaque handle for a secure context. */ typedef uint32_t SecureContextHandle_t; /*-----------------------------------------------------------*/ /** * @brief Initializes the secure context management system. * * PSP is set to NULL and therefore a task must allocate and load a context * before calling any secure side function in the thread mode. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureContext_Init( void ); /** * @brief Allocates a context on the secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] ulSecureStackSize Size of the stack to allocate on secure side. * @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise. * * @return Opaque context handle if context is successfully allocated, NULL * otherwise. */ #if ( configENABLE_MPU == 1 ) SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ); #else /* configENABLE_MPU */ SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ); #endif /* configENABLE_MPU */ /** * @brief Frees the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the * context to be freed. */ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Loads the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be loaded. */ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Saves the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be saved. */ void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); #endif /* __SECURE_CONTEXT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55/secure/secure_context_port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Secure context includes. */ #include "secure_context.h" /* Secure port macros. */ #include "secure_port_macros.h" void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) { /* pxSecureContext value is in r0. */ __asm volatile ( " .syntax unified \n" " \n" " mrs r1, ipsr \n" /* r1 = IPSR. */ " cbz r1, load_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */ " ldmia r0!, {r1, r2} \n" /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */ " \n" #if ( configENABLE_MPU == 1 ) " ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */ " msr control, r3 \n" /* CONTROL = r3. */ #endif /* configENABLE_MPU */ " \n" " msr psplim, r2 \n" /* PSPLIM = r2. */ " msr psp, r1 \n" /* PSP = r1. */ " \n" " load_ctx_therad_mode: \n" " bx lr \n" " \n" ::: "r0", "r1", "r2" ); } /*-----------------------------------------------------------*/ void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) { /* pxSecureContext value is in r0. */ __asm volatile ( " .syntax unified \n" " \n" " mrs r1, ipsr \n" /* r1 = IPSR. */ " cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */ " mrs r1, psp \n" /* r1 = PSP. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " vstmdb r1!, {s0} \n" /* Trigger the deferred stacking of FPU registers. */ " vldmia r1!, {s0} \n" /* Nullify the effect of the previous statement. */ #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" #if ( configENABLE_MPU == 1 ) " mrs r2, control \n" /* r2 = CONTROL. */ " stmdb r1!, {r2} \n" /* Store CONTROL value on the stack. */ #endif /* configENABLE_MPU */ " \n" " str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ " movs r1, %0 \n" /* r1 = securecontextNO_STACK. */ " msr psplim, r1 \n" /* PSPLIM = securecontextNO_STACK. */ " msr psp, r1 \n" /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */ " \n" " save_ctx_therad_mode: \n" " bx lr \n" " \n" ::"i" ( securecontextNO_STACK ) : "r1", "memory" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55/secure/secure_heap.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure context heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Total heap size. */ #ifndef secureconfigTOTAL_HEAP_SIZE #define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) ) #endif /* No test marker by default. */ #ifndef mtCOVERAGE_TEST_MARKER #define mtCOVERAGE_TEST_MARKER() #endif /* No tracing by default. */ #ifndef traceMALLOC #define traceMALLOC( pvReturn, xWantedSize ) #endif /* No tracing by default. */ #ifndef traceFREE #define traceFREE( pv, xBlockSize ) #endif /* Block sizes must not get too small. */ #define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) /* Assumes 8bit bytes! */ #define secureheapBITS_PER_BYTE ( ( size_t ) 8 ) /*-----------------------------------------------------------*/ /* Allocate the memory for the heap. */ #if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) /* The application writer has already defined the array used for the RTOS * heap - probably so it can be placed in a special segment or address. */ extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #else /* configAPPLICATION_ALLOCATED_HEAP */ static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #endif /* configAPPLICATION_ALLOCATED_HEAP */ /** * @brief The linked list structure. * * This is used to link free blocks in order of their memory address. */ typedef struct A_BLOCK_LINK { struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */ size_t xBlockSize; /**< The size of the free block. */ } BlockLink_t; /*-----------------------------------------------------------*/ /** * @brief Called automatically to setup the required heap structures the first * time pvPortMalloc() is called. */ static void prvHeapInit( void ); /** * @brief Inserts a block of memory that is being freed into the correct * position in the list of free memory blocks. * * The block being freed will be merged with the block in front it and/or the * block behind it if the memory blocks are adjacent to each other. * * @param[in] pxBlockToInsert The block being freed. */ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ); /*-----------------------------------------------------------*/ /** * @brief The size of the structure placed at the beginning of each allocated * memory block must by correctly byte aligned. */ static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); /** * @brief Create a couple of list links to mark the start and end of the list. */ static BlockLink_t xStart; static BlockLink_t * pxEnd = NULL; /** * @brief Keeps track of the number of free bytes remaining, but says nothing * about fragmentation. */ static size_t xFreeBytesRemaining = 0U; static size_t xMinimumEverFreeBytesRemaining = 0U; /** * @brief Gets set to the top bit of an size_t type. * * When this bit in the xBlockSize member of an BlockLink_t structure is set * then the block belongs to the application. When the bit is free the block is * still part of the free heap space. */ static size_t xBlockAllocatedBit = 0; /*-----------------------------------------------------------*/ static void prvHeapInit( void ) { BlockLink_t * pxFirstFreeBlock; uint8_t * pucAlignedHeap; size_t uxAddress; size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE; /* Ensure the heap starts on a correctly aligned boundary. */ uxAddress = ( size_t ) ucHeap; if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 ) { uxAddress += ( secureportBYTE_ALIGNMENT - 1 ); uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; } pucAlignedHeap = ( uint8_t * ) uxAddress; /* xStart is used to hold a pointer to the first item in the list of free * blocks. The void cast is used to prevent compiler warnings. */ xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; xStart.xBlockSize = ( size_t ) 0; /* pxEnd is used to mark the end of the list of free blocks and is inserted * at the end of the heap space. */ uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; uxAddress -= xHeapStructSize; uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); pxEnd = ( void * ) uxAddress; pxEnd->xBlockSize = 0; pxEnd->pxNextFreeBlock = NULL; /* To start with there is a single free block that is sized to take up the * entire heap space, minus the space taken by pxEnd. */ pxFirstFreeBlock = ( void * ) pucAlignedHeap; pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; pxFirstFreeBlock->pxNextFreeBlock = pxEnd; /* Only one block exists - and it covers the entire usable heap space. */ xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; /* Work out the position of the top bit in a size_t variable. */ xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 ); } /*-----------------------------------------------------------*/ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) { BlockLink_t * pxIterator; uint8_t * puc; /* Iterate through the list until a block is found that has a higher address * than the block being inserted. */ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) { /* Nothing to do here, just iterate to the right position. */ } /* Do the block being inserted, and the block it is being inserted after * make a contiguous block of memory? */ puc = ( uint8_t * ) pxIterator; if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) { pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; pxBlockToInsert = pxIterator; } else { mtCOVERAGE_TEST_MARKER(); } /* Do the block being inserted, and the block it is being inserted before * make a contiguous block of memory? */ puc = ( uint8_t * ) pxBlockToInsert; if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) { if( pxIterator->pxNextFreeBlock != pxEnd ) { /* Form one big block from the two blocks. */ pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; } else { pxBlockToInsert->pxNextFreeBlock = pxEnd; } } else { pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } /* If the block being inserted plugged a gab, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ if( pxIterator != pxBlockToInsert ) { pxIterator->pxNextFreeBlock = pxBlockToInsert; } else { mtCOVERAGE_TEST_MARKER(); } } /*-----------------------------------------------------------*/ void * pvPortMalloc( size_t xWantedSize ) { BlockLink_t * pxBlock; BlockLink_t * pxPreviousBlock; BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ if( pxEnd == NULL ) { prvHeapInit(); } else { mtCOVERAGE_TEST_MARKER(); } /* Check the requested block size is not so large that the top bit is set. * The top bit of the block size member of the BlockLink_t structure is used * to determine who owns the block - the application or the kernel, so it * must be free. */ if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) { /* The wanted size is increased so it can contain a BlockLink_t * structure in addition to the requested amount of bytes. */ if( xWantedSize > 0 ) { xWantedSize += xHeapStructSize; /* Ensure that blocks are always aligned to the required number of * bytes. */ if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 ) { /* Byte alignment required. */ xWantedSize += ( secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) ); secureportASSERT( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) == 0 ); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) { /* Traverse the list from the start (lowest address) block until * one of adequate size is found. */ pxPreviousBlock = &xStart; pxBlock = xStart.pxNextFreeBlock; while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) { pxPreviousBlock = pxBlock; pxBlock = pxBlock->pxNextFreeBlock; } /* If the end marker was reached then a block of adequate size was * not found. */ if( pxBlock != pxEnd ) { /* Return the memory space pointed to - jumping over the * BlockLink_t structure at its start. */ pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); /* This block is being returned for use so must be taken out * of the list of free blocks. */ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; /* If the block is larger than required it can be split into * two. */ if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE ) { /* This block is to be split into two. Create a new * block following the number of bytes requested. The void * cast is used to prevent byte alignment warnings from the * compiler. */ pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 ); /* Calculate the sizes of two blocks split from the single * block. */ pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; pxBlock->xBlockSize = xWantedSize; /* Insert the new block into the list of free blocks. */ prvInsertBlockIntoFreeList( pxNewBlockLink ); } else { mtCOVERAGE_TEST_MARKER(); } xFreeBytesRemaining -= pxBlock->xBlockSize; if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) { xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; } else { mtCOVERAGE_TEST_MARKER(); } /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ pxBlock->xBlockSize |= xBlockAllocatedBit; pxBlock->pxNextFreeBlock = NULL; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } traceMALLOC( pvReturn, xWantedSize ); #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { extern void vApplicationMallocFailedHook( void ); vApplicationMallocFailedHook(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */ secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 ); return pvReturn; } /*-----------------------------------------------------------*/ void vPortFree( void * pv ) { uint8_t * puc = ( uint8_t * ) pv; BlockLink_t * pxLink; if( pv != NULL ) { /* The memory being freed will have an BlockLink_t structure immediately * before it. */ puc -= xHeapStructSize; /* This casting is to keep the compiler from issuing warnings. */ pxLink = ( void * ) puc; /* Check the block is actually allocated. */ secureportASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); secureportASSERT( pxLink->pxNextFreeBlock == NULL ); if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) { if( pxLink->pxNextFreeBlock == NULL ) { /* The block is being returned to the heap - it is no longer * allocated. */ pxLink->xBlockSize &= ~xBlockAllocatedBit; secureportDISABLE_NON_SECURE_INTERRUPTS(); { /* Add this block to the list of free blocks. */ xFreeBytesRemaining += pxLink->xBlockSize; traceFREE( pv, pxLink->xBlockSize ); prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); } secureportENABLE_NON_SECURE_INTERRUPTS(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } } /*-----------------------------------------------------------*/ size_t xPortGetFreeHeapSize( void ) { return xFreeBytesRemaining; } /*-----------------------------------------------------------*/ size_t xPortGetMinimumEverFreeHeapSize( void ) { return xMinimumEverFreeBytesRemaining; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55/secure/secure_heap.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_HEAP_H__ #define __SECURE_HEAP_H__ /* Standard includes. */ #include /** * @brief Allocates memory from heap. * * @param[in] xWantedSize The size of the memory to be allocated. * * @return Pointer to the memory region if the allocation is successful, NULL * otherwise. */ void * pvPortMalloc( size_t xWantedSize ); /** * @brief Frees the previously allocated memory. * * @param[in] pv Pointer to the memory to be freed. */ void vPortFree( void * pv ); /** * @brief Get the free heap size. * * @return Free heap size. */ size_t xPortGetFreeHeapSize( void ); /** * @brief Get the minimum ever free heap size. * * @return Minimum ever free heap size. */ size_t xPortGetMinimumEverFreeHeapSize( void ); #endif /* __SECURE_HEAP_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55/secure/secure_init.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure init includes. */ #include "secure_init.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Constants required to manipulate the SCB. */ #define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */ #define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL ) #define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS ) #define secureinitSCB_AIRCR_PRIS_POS ( 14UL ) #define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS ) /** * @brief Constants required to manipulate the FPU. */ #define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define secureinitFPCCR_LSPENS_POS ( 29UL ) #define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS ) #define secureinitFPCCR_TS_POS ( 26UL ) #define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS ) #define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */ #define secureinitNSACR_CP10_POS ( 10UL ) #define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS ) #define secureinitNSACR_CP11_POS ( 11UL ) #define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS ) /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { *( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) | ( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) | ( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK ); } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* CP10 = 1 ==> Non-secure access to the Floating Point Unit is * permitted. CP11 should be programmed to the same value as CP10. */ *( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK ); /* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures * that we can enable/disable lazy stacking in port.c file. */ *( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK ); /* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP * registers (S16-S31) are also pushed to stack on exception entry and * restored on exception return. */ *( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK ); } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55/secure/secure_init.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_INIT_H__ #define __SECURE_INIT_H__ /** * @brief De-prioritizes the non-secure exceptions. * * This is needed to ensure that the non-secure PendSV runs at the lowest * priority. Context switch is done in the non-secure PendSV handler. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_DePrioritizeNSExceptions( void ); /** * @brief Sets up the Floating Point Unit (FPU) for Non-Secure access. * * Also sets FPCCR.TS=1 to ensure that the content of the Floating Point * Registers are not leaked to the non-secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_EnableNSFPUAccess( void ); #endif /* __SECURE_INIT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55/secure/secure_port_macros.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_PORT_MACROS_H__ #define __SECURE_PORT_MACROS_H__ /** * @brief Byte alignment requirements. */ #define secureportBYTE_ALIGNMENT 8 #define secureportBYTE_ALIGNMENT_MASK ( 0x0007 ) /** * @brief Macro to declare a function as non-secure callable. */ #if defined( __IAR_SYSTEMS_ICC__ ) #define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root #else #define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) ) #endif /** * @brief Set the secure PRIMASK value. */ #define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Set the non-secure PRIMASK value. */ #define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Read the PSP value in the given variable. */ #define secureportREAD_PSP( pucOutCurrentStackPointer ) \ __asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) ) /** * @brief Set the PSP to the given value. */ #define secureportSET_PSP( pucCurrentStackPointer ) \ __asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) ) /** * @brief Read the PSPLIM value in the given variable. */ #define secureportREAD_PSPLIM( pucOutStackLimit ) \ __asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) ) /** * @brief Set the PSPLIM to the given value. */ #define secureportSET_PSPLIM( pucStackLimit ) \ __asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) ) /** * @brief Set the NonSecure MSP to the given value. */ #define secureportSET_MSP_NS( pucMainStackPointer ) \ __asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) ) /** * @brief Set the CONTROL register to the given value. */ #define secureportSET_CONTROL( ulControl ) \ __asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" ) /** * @brief Read the Interrupt Program Status Register (IPSR) value in the given * variable. */ #define secureportREAD_IPSR( ulIPSR ) \ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) ) /** * @brief PRIMASK value to enable interrupts. */ #define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0 /** * @brief PRIMASK value to disable interrupts. */ #define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1 /** * @brief Disable secure interrupts. */ #define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Disable non-secure interrupts. * * This effectively disables context switches. */ #define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Enable non-secure interrupts. */ #define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL ) /** * @brief Assert definition. */ #define secureportASSERT( x ) \ if( ( x ) == 0 ) \ { \ secureportDISABLE_SECURE_INTERRUPTS(); \ secureportDISABLE_NON_SECURE_INTERRUPTS(); \ for( ; ; ) {; } \ } #endif /* __SECURE_PORT_MACROS_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55_NTZ/non_secure/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /* Portasm includes. */ #include "portasm.h" #if ( configENABLE_TRUSTZONE == 1 ) /* Secure components includes. */ #include "secure_context.h" #include "secure_init.h" #endif /* configENABLE_TRUSTZONE */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /** * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS * on the secure side. The following are the valid configuration seetings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 * * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 * * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 */ #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. #endif /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the SCB. */ #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the FPU. */ #define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) #define portMPU_RLAR_REGION_ENABLE ( 1UL ) /* Enable privileged access to unmapped region. */ #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /*-----------------------------------------------------------*/ /** * @brief The maximum 24-bit number. * * It is needed because the systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /** * @brief A fiddle factor to estimate the number of SysTick counts that would * have occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) /** * @brief Initial EXC_RETURN value. * * FF FF FF FD * 1111 1111 1111 1111 1111 1111 1111 1101 * * Bit[6] - 1 --> The exception was taken from the Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 1 --> The exception was taken to the Secure state. */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else /** * @brief Initial EXC_RETURN value. * * FF FF FF BC * 1111 1111 1111 1111 1111 1111 1011 1100 * * Bit[6] - 0 --> The exception was taken from the Non-Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 0 --> The exception was taken to the Non-Secure state. */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ /** * @brief CONTROL register privileged bit mask. * * Bit[0] in CONTROL register tells the privilege: * Bit[0] = 0 ==> The task is privileged. * Bit[0] = 1 ==> The task is not privileged. */ #define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) /** * @brief Initial CONTROL register values. */ #define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) #define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) /** * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /** * @brief 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /** * @brief If portPRELOAD_REGISTERS then registers will be given an initial value * when a task is created. This helps in debugging at the cost of code size. */ #define portPRELOAD_REGISTERS 1 /** * @brief A task is created without a secure context, and must call * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes * any secure calls. */ #define portNO_SECURE_CONTEXT 0 /*-----------------------------------------------------------*/ /** * @brief Used to catch tasks that attempt to return from their implementing * function. */ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) /** * @brief Setup the Memory Protection Unit (MPU). */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) /** * @brief Setup the Floating Point Unit (FPU). */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ /** * @brief Setup the timer to generate the tick interrupts. * * The implementation in this file is weak to allow application writers to * change the timer used to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /** * @brief Checks whether the current execution context is interrupt. * * @return pdTRUE if the current execution context is interrupt, pdFALSE * otherwise. */ BaseType_t xPortIsInsideInterrupt( void ); /** * @brief Yield the processor. */ void vPortYield( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ void vPortExitCritical( void ) PRIVILEGED_FUNCTION; /** * @brief SysTick handler. */ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; /** * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. */ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Saved as part of the task context to indicate which context the * task is using on the secure side. */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ #if ( configUSE_TICKLESS_IDLE == 1 ) /** * @brief The number of SysTick increments that make up one tick period. */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; /** * @brief The maximum number of tick periods that can be suppressed is * limited by the 24 bit resolution of the SysTick timer. */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; /** * @brief Compensate for the CPU cycles that pass while the SysTick is * stopped (low power functionality only). */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). Artificially force an assert() * to be triggered if configASSERT() is defined, then stop here so * application writers can catch the error. */ configASSERT( ulCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being * defined but never called. ulDummy is used purely to quieten other * warnings about code appearing after this function is called - making * ulDummy volatile makes the compiler think the function could return * and therefore not output an 'unreachable code' warning for code that * appears after it. */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; extern uint32_t * __unprivileged_flash_start__; extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* if defined( __ARMCC_VERSION ) */ /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; extern uint32_t __unprivileged_flash_start__[]; extern uint32_t __unprivileged_flash_end__[]; extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check that the MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* MAIR0 - Index 0. */ portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); /* MAIR0 - Index 1. */ portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* Setup privileged flash as Read Only so that privileged tasks can * read it but not modify. */ portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged flash as Read Only by both privileged and * unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged syscalls flash as Read Only by both privileged * and unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup RAM containing kernel data for privileged access only. */ portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Enable mem fault. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; /* Enable MPU with privileged background access i.e. unmapped * regions have privileged access. */ portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) { /* Enable non-secure access to the FPU. */ SecureInit_EnableNSFPUAccess(); } #endif /* configENABLE_TRUSTZONE */ /* CP10 = 11 ==> Full access to FPU i.e. both privileged and * unprivileged code should be able to access FPU. CP11 should be * programmed to the same value as CP10. */ *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) ); /* ASPEN = 1 ==> Hardware should automatically preserve floating point * context on exception entry and restore on exception return. * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ void vPortYield( void ) /* PRIVILEGED_FUNCTION */ { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ { portDISABLE_INTERRUPTS(); ulCriticalNesting++; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ { configASSERT( ulCriticalNesting ); ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { #if ( configENABLE_MPU == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ #endif /* configENABLE_MPU */ uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) uint32_t ulR0, ulR1; extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ #endif /* configENABLE_TRUSTZONE */ uint8_t ucSVCNumber; /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ ulPC = pulCallerStackAddress[ 6 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { #if ( configENABLE_TRUSTZONE == 1 ) case portSVC_ALLOCATE_SECURE_CONTEXT: /* R0 contains the stack size passed as parameter to the * vPortAllocateSecureContext function. */ ulR0 = pulCallerStackAddress[ 0 ]; #if ( configENABLE_MPU == 1 ) { /* Read the CONTROL register value. */ __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); /* The task that raised the SVC is privileged if Bit[0] * in the CONTROL register is 0. */ ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: /* R0 contains TCB being freed and R1 contains the secure * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) { /* De-prioritize the non-secure exceptions so that the * non-secure pendSV runs at the lowest priority. */ SecureInit_DePrioritizeNSExceptions(); /* Initialize the secure context management system. */ SecureContext_Init(); } #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_FPU == 1 ) { /* Setup the Floating Point Unit (FPU). */ prvSetupFPU(); } #endif /* configENABLE_FPU */ /* Setup the context of the first task so that the first task starts * executing. */ vRestoreContextOfFirstTask(); break; #if ( configENABLE_MPU == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the svc was raised from any of * the system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { vRaisePrivilege(); } break; #endif /* configENABLE_MPU */ default: /* Incorrect SVC call. */ configASSERT( pdFALSE ); } } /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #if ( configENABLE_MPU == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /* *INDENT-ON* */ { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #endif /* portPRELOAD_REGISTERS */ return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ prvSetupMPU(); } #endif /* configENABLE_MPU */ /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; /* Start the first task. */ vStartFirstTask(); /* Should never get here as the tasks will now be executing. Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* Setup MAIR0. */ xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ if( ulStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged * SRAM is already protected using an MPU region and ARMv8-M does * not allow overlapping MPU regions. */ if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) { xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; } else { /* Define the region that allows access to the stack. */ ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); } } /* User supplied configurable regions. */ for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) { /* If xRegions is NULL i.e. the task has not specified any MPU * region, the else part ensures that all the configurable MPU * regions are invalidated. */ if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) { /* Translate the generic region definition contained in xRegions * into the ARMv8 specific MPU settings that are then stored in * xMPUSettings. */ ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; /* Start address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ); /* RO/RW. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); } else { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); } /* XN. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); } /* End Address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { /* Attr1 in MAIR0 is configured as device memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; } else { /* Attr0 in MAIR0 is configured as normal memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; } } else { /* Invalidate the region. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; } lIndex++; } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. Interrupt Program * Status Register (IPSR) holds the exception number of the currently-executing * exception or zero for Thread mode.*/ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION * is defined correctly and privileged functions are placed in correct sections. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Portasm includes. */ #include "portasm.h" /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r4, [r2] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r3, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #4 \n"/* r3 = 4. */ " str r3, [r2] \n"/* Program RNR = 4. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #8 \n"/* r3 = 8. */ " str r3, [r2] \n"/* Program RNR = 8. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #12 \n"/* r3 = 12. */ " str r3, [r2] \n"/* Program RNR = 12. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " str r4, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ " msr control, r2 \n"/* Set this task's CONTROL value. */ " 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. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " bx r3 \n"/* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ " movs r1, #2 \n"/* r1 = 2. */ " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ " 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. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " bx r2 \n"/* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst2: .word 0xe000ed94 \n" "xMAIR0Const2: .word 0xe000edc0 \n" "xRNRConst2: .word 0xe000ed98 \n" "xRBARConst2: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ " ite ne \n" " 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. */ " bx lr \n"/* Return. */ " \n" " .align 4 \n" ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* Read the CONTROL register. */ " bic r0, #1 \n"/* Clear the bit 0. */ " msr control, r0 \n"/* Write back the new CONTROL value. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vResetPrivilege( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " orr r0, #1 \n"/* r0 = r0 | 1. */ " msr control, r0 \n"/* CONTROL = r0. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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"/* The first entry in vector table is stack pointer. */ " msr msp, r0 \n"/* Set the MSP back to the start of the stack. */ " cpsie i \n"/* Globally enable interrupts. */ " cpsie f \n" " dsb \n" " isb \n" " svc %0 \n"/* System call to start the first task. */ " nop \n" " \n" " .align 4 \n" "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } /*-----------------------------------------------------------*/ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n"/* Return. */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); } /*-----------------------------------------------------------*/ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " msr basepri, r0 \n"/* basepri = ulMask. */ " dsb \n" " isb \n" " bx lr \n"/* Return. */ ::: "memory" ); } /*-----------------------------------------------------------*/ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, psp \n"/* Read PSP in r0. */ #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. */ " it eq \n" " vstmdbeq r0!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r2, control \n"/* r2 = CONTROL. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r1-r11} \n"/* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ #else /* configENABLE_MPU */ " mrs r2, psplim \n"/* r2 = PSPLIM. */ " 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. */ #endif /* configENABLE_MPU */ " \n" " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " str r0, [r1] \n"/* Save the new top of stack in TCB. */ " \n" " mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" " mov r0, #0 \n"/* r0 = 0. */ " msr basepri, r0 \n"/* Enable interrupts. */ " \n" " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r4, [r2] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r3, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #4 \n"/* r3 = 4. */ " str r3, [r2] \n"/* Program RNR = 4. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #8 \n"/* r3 = 8. */ " str r3, [r2] \n"/* Program RNR = 8. */ " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #12 \n"/* r3 = 12. */ " str r3, [r2] \n"/* Program RNR = 12. */ " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " str r4, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldmia r0!, {r1-r11} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ #else /* configENABLE_MPU */ " ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #endif /* configENABLE_MPU */ " \n" #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. */ " it eq \n" " vldmiaeq r0!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" #if ( configENABLE_MPU == 1 ) " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ " msr control, r2 \n"/* Restore the CONTROL register value for the task. */ #else /* configENABLE_MPU */ " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ #endif /* configENABLE_MPU */ " msr psp, r0 \n"/* Remember the new top of stack for the task. */ " bx r3 \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst: .word 0xe000ed94 \n" "xMAIR0Const: .word 0xe000edc0 \n" "xRNRConst: .word 0xe000ed98 \n" "xRBARConst: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } /*-----------------------------------------------------------*/ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " tst lr, #4 \n" " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" " ldr r1, svchandler_address_const \n" " bx r1 \n" " \n" " .align 4 \n" "svchandler_address_const: .word vPortSVCHandler_C \n" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORT_ASM_H__ #define __PORT_ASM_H__ /* Scheduler includes. */ #include "FreeRTOS.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /** * @brief Restore the context of the first task so that the first task starts * executing. */ void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * * @note This is a privileged function and should only be called from the kenrel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Starts the first task. */ void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Disables interrupts. */ uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Enables interrupts. */ void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief PendSV Exception handler. */ void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief SVC Handler. */ void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Allocate a Secure context for the calling task. * * @param[in] ulSecureStackSize The size of the stack to be allocated on the * secure side for the calling task. */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); /** * @brief Free the task's secure context. * * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. */ void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* __PORT_ASM_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_MVE #error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE. #endif /* configENABLE_MVE */ /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M55" #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACROCOMMON_H #define PORTMACROCOMMON_H #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_FPU #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. #endif /* configENABLE_FPU */ #ifndef configENABLE_MPU #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. #endif /* configENABLE_MPU */ #ifndef configENABLE_TRUSTZONE #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ /** * @brief Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif #define portHAS_STACK_OVERFLOW_CHECKING 1 /*-----------------------------------------------------------*/ /** * @brief Extern declarations. */ extern BaseType_t xPortIsInsideInterrupt( void ); extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; #if ( configENABLE_TRUSTZONE == 1 ) extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_MPU == 1 ) extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief MPU specific constants. */ #if ( configENABLE_MPU == 1 ) #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #else #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* MPU regions. */ #define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_RAM_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ /* Device memory attributes used in MPU_MAIR registers. * * 8-bit values encoded as follows: * Bit[7:4] - 0000 - Device Memory * Bit[3:2] - 00 --> Device-nGnRnE * 01 --> Device-nGnRE * 10 --> Device-nGRE * 11 --> Device-GRE * Bit[1:0] - 00, Reserved. */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ /* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ /* Attributes used in MPU_RBAR registers. */ #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ /** * @brief Settings to define an MPU region. */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */ } MPURegionSettings_t; /** * @brief MPU settings as stored in the TCB. */ typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ } xMPU_SETTINGS; /*-----------------------------------------------------------*/ /** * @brief SVC numbers. */ #define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 /*-----------------------------------------------------------*/ /** * @brief Scheduler utilities. */ #define portYIELD() vPortYield() #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /** * @brief Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /** * @brief Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Allocate a secure context for the task. * * 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 context before it calls any secure function. * * @param[in] ulSecureStackSize The size of the secure stack to be allocated. */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) /** * @brief Called when a task is deleted to delete the task's secure context, * if it has one. * * @param[in] pxTCB The TCB of the task being deleted. */ #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. * * 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, * the privilege is not raised. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() #else #define portIS_PRIVILEGED() #define portRAISE_PRIVILEGE() #define portRESET_PRIVILEGE() #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief Barriers. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACROCOMMON_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM7/ReadMe.txt ================================================ There are two options for running FreeRTOS on ARM Cortex-M7 microcontrollers. The best option depends on the revision of the ARM Cortex-M7 core in use. The revision is specified by an 'r' number, and a 'p' number, so will look something like 'r0p1'. Check the documentation for the microcontroller in use to find the revision of the Cortex-M7 core used in that microcontroller. If in doubt, use the FreeRTOS port provided specifically for r0p1 revisions, as that can be used with all core revisions. The first option is to use the ARM Cortex-M4F port, and the second option is to use the Cortex-M7 r0p1 port - the latter containing a minor errata workaround. If the revision of the ARM Cortex-M7 core is not r0p1 then either option can be used, but it is recommended to use the FreeRTOS ARM Cortex-M4F port located in the /FreeRTOS/Source/portable/GCC/ARM_CM4F directory. If the revision of the ARM Cortex-M7 core is r0p1 then use the FreeRTOS ARM Cortex-M7 r0p1 port located in the /FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1 directory. ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM7/r0p1/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM7 port. *----------------------------------------------------------*/ /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #ifndef __VFP_FP__ #error This port can only be used when the project options are configured to enable hardware floating point support. #endif /* Constants required to manipulate the core. Registers first... */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) /* ...then bits in the registers. */ #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) #define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) ) #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ #define portVECTACTIVE_MASK ( 0xFFUL ) /* Constants required to manipulate the VFP. */ #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_EXC_RETURN ( 0xfffffffd ) /* The systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) /* A fiddle factor to estimate the number of SysTick counts that would have * occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /* Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /* 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 * debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ); /* * Exception handlers. */ void xPortPendSVHandler( void ) __attribute__( ( naked ) ); void xPortSysTickHandler( void ); void vPortSVCHandler( void ) __attribute__( ( naked ) ); /* * Start first task is a separate function so it can be tested in isolation. */ static void prvPortStartFirstTask( void ) __attribute__( ( naked ) ); /* * Function to enable the VFP. */ static void vPortEnableVFP( void ) __attribute__( ( naked ) ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* Each task maintains its own interrupt status in the critical nesting * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* * The number of SysTick increments that make up one tick period. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulTimerCountsForOneTick = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * The maximum number of tick periods that can be suppressed is limited by the * 24 bit resolution of the SysTick timer. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t xMaximumPossibleSuppressedTicks = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Compensate for the CPU cycles that pass while the SysTick is stopped (low * power functionality only. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. */ #if ( configASSERT_DEFINED == 1 ) static uint8_t ucMaxSysCallPriority = 0; static uint32_t ulMaxPRIGROUPValue = 0; static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ /* Offset added to account for the way the MCU uses the stack on entry/exit * of interrupts, and to ensure alignment. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ /* Save code space by skipping register initialisation. */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ /* A save method is being used that requires each task to maintain its * own exec return value. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). * * Artificially force an assert() to be triggered if configASSERT() is * defined, then stop here so application writers can catch the error. */ configASSERT( uxCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being defined * but never called. ulDummy is used purely to quieten other warnings * about code appearing after this function is called - making ulDummy * volatile makes the compiler think the function could return and * therefore not output an 'unreachable code' warning for code that appears * after it. */ } } /*-----------------------------------------------------------*/ void vPortSVCHandler( void ) { __asm volatile ( " ldr r3, pxCurrentTCBConst2 \n"/* Restore the context. */ " ldr r1, [r3] \n"/* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. */ " ldmia r0!, {r4-r11, r14} \n"/* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ " msr psp, r0 \n"/* Restore the task stack pointer. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n" " bx r14 \n" " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" ); } /*-----------------------------------------------------------*/ static void prvPortStartFirstTask( void ) { /* Start the first task. This also clears the bit that indicates the FPU is * in use in case the FPU was used before the scheduler was started - which * would otherwise result in the unnecessary leaving of space in the SVC stack * for lazy saving of FPU registers. */ __asm volatile ( " ldr r0, =0xE000ED08 \n"/* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" " ldr r0, [r0] \n" " msr msp, r0 \n"/* Set the msp back to the start of the stack. */ " mov r0, #0 \n"/* Clear the bit that indicates the FPU is in use, see comment above. */ " msr control, r0 \n" " cpsie i \n"/* Globally enable interrupts. */ " cpsie f \n" " dsb \n" " isb \n" " svc 0 \n"/* System call to start first task. */ " nop \n" " .ltorg \n" ); } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API * functions can be called. ISR safe functions are those that end in * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { ulMaxPRIGROUPValue--; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); } #endif /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; /* Restore the clobbered interrupt priority register to its original * value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Ensure the VFP is enabled - it should be anyway. */ vPortEnableVFP(); /* Lazy save always. */ *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; /* Start the first task. */ prvPortStartFirstTask(); /* Should never get here as the tasks will now be executing! Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimisation does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); uxCriticalNesting++; /* 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 * 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 * assert function also uses a critical section. */ if( uxCriticalNesting == 1 ) { configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void xPortPendSVHandler( void ) { /* This is a naked function. */ __asm volatile ( " mrs r0, psp \n" " isb \n" " \n" " ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */ " ldr r2, [r3] \n" " \n" " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, push high vfp registers. */ " it eq \n" " vstmdbeq r0!, {s16-s31} \n" " \n" " stmdb r0!, {r4-r11, r14} \n"/* Save the core registers. */ " str r0, [r2] \n"/* Save the new top of stack into the first member of the TCB. */ " \n" " stmdb sp!, {r0, r3} \n" " mov r0, %0 \n" " cpsid i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ " msr basepri, r0 \n" " dsb \n" " isb \n" " cpsie i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ " bl vTaskSwitchContext \n" " mov r0, #0 \n" " msr basepri, r0 \n" " ldmia sp!, {r0, r3} \n" " \n" " ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. */ " ldr r0, [r1] \n" " \n" " ldmia r0!, {r4-r11, r14} \n"/* Pop the core registers. */ " \n" " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, pop the high vfp registers too. */ " it eq \n" " vldmiaeq r0!, {s16-s31} \n" " \n" " msr psp, r0 \n" " isb \n" " \n" #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */ #if WORKAROUND_PMU_CM001 == 1 " push { r14 } \n" " pop { pc } \n" #endif #endif " \n" " bx r14 \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { /* The SysTick runs at the lowest interrupt priority, so when this interrupt * executes all interrupts must be unmasked. There is therefore no need to * save and then restore the interrupt mask value as its value is already * known. */ portDISABLE_INTERRUPTS(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* A context switch is required. Context switching is performed in * the PendSV interrupt. Pend the PendSV interrupt. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portENABLE_INTERRUPTS(); } /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* #if configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ /* * Setup the systick timer to generate the tick interrupts at the required * frequency. */ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and clear the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); } /*-----------------------------------------------------------*/ /* This is a naked function. */ static void vPortEnableVFP( void ) { __asm volatile ( " ldr.w r0, =0xE000ED88 \n"/* The FPU enable bits are in the CPACR. */ " ldr r1, [r0] \n" " \n" " orr r1, r1, #( 0xf << 20 ) \n"/* Enable CP10 and CP11 coprocessors, then save back. */ " str r1, [r0] \n" " bx r14 \n" " .ltorg \n" ); } /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); /* Is the interrupt number a user defined interrupt? */ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /* Look up the interrupt's priority. */ ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Interrupts that use the FreeRTOS API must not be left at their * default priority of zero as that is the highest possible priority, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * and therefore also guaranteed to be invalid. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } /* Priority grouping: The interrupt controller (NVIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined * to be pre-emption priority bits. The following assertion will fail if * this is not the case (if some bits represent a sub-priority). * * If the application only uses CMSIS libraries for interrupt * configuration then the correct setting can be achieved on all Cortex-M * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * scheduler. Note however that some vendor specific peripheral libraries * assume a non-zero priority group setting, in which cases using a value * of zero will result in unpredictable behaviour. */ configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); } #endif /* configASSERT_DEFINED */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM7/r0p1/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ #define portYIELD() \ { \ /* Set a PendSV to request a context switch. */ \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ \ /* Barriers are normally not required but do ensure the code is completely \ * within the specified behaviour for the architecture. */ \ __asm volatile ( "dsb" ::: "memory" ); \ __asm volatile ( "isb" ); \ } #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x ) #define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() #define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /* 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 * (which build with all the ports) will build. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Generic helper function. */ __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) { uint8_t ucReturn; __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" ); return ucReturn; } /* Check the configuration. */ #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. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /*-----------------------------------------------------------*/ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* portNOP() is not required by this port. */ #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ portFORCE_INLINE static void vPortRaiseBASEPRI( void ) { uint32_t ulNewBASEPRI; __asm volatile ( " mov %0, %1 \n"\ " cpsid i \n"\ " msr basepri, %0 \n"\ " isb \n"\ " dsb \n"\ " cpsie i \n"\ : "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); } /*-----------------------------------------------------------*/ portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) { uint32_t ulOriginalBASEPRI, ulNewBASEPRI; __asm volatile ( " mrs %0, basepri \n"\ " mov %1, %2 \n"\ " cpsid i \n"\ " msr basepri, %1 \n"\ " isb \n"\ " dsb \n"\ " cpsie i \n"\ : "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); /* This return will not be reached but is necessary to prevent compiler * warnings. */ return ulOriginalBASEPRI; } /*-----------------------------------------------------------*/ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) { __asm volatile ( " msr basepri, %0 "::"r" ( ulNewMaskValue ) : "memory" ); } /*-----------------------------------------------------------*/ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85/non_secure/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /* Portasm includes. */ #include "portasm.h" #if ( configENABLE_TRUSTZONE == 1 ) /* Secure components includes. */ #include "secure_context.h" #include "secure_init.h" #endif /* configENABLE_TRUSTZONE */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /** * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS * on the secure side. The following are the valid configuration seetings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 * * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 * * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 */ #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. #endif /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the SCB. */ #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the FPU. */ #define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) #define portMPU_RLAR_REGION_ENABLE ( 1UL ) /* Enable privileged access to unmapped region. */ #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /*-----------------------------------------------------------*/ /** * @brief The maximum 24-bit number. * * It is needed because the systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /** * @brief A fiddle factor to estimate the number of SysTick counts that would * have occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) /** * @brief Initial EXC_RETURN value. * * FF FF FF FD * 1111 1111 1111 1111 1111 1111 1111 1101 * * Bit[6] - 1 --> The exception was taken from the Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 1 --> The exception was taken to the Secure state. */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else /** * @brief Initial EXC_RETURN value. * * FF FF FF BC * 1111 1111 1111 1111 1111 1111 1011 1100 * * Bit[6] - 0 --> The exception was taken from the Non-Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 0 --> The exception was taken to the Non-Secure state. */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ /** * @brief CONTROL register privileged bit mask. * * Bit[0] in CONTROL register tells the privilege: * Bit[0] = 0 ==> The task is privileged. * Bit[0] = 1 ==> The task is not privileged. */ #define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) /** * @brief Initial CONTROL register values. */ #define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) #define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) /** * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /** * @brief 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /** * @brief If portPRELOAD_REGISTERS then registers will be given an initial value * when a task is created. This helps in debugging at the cost of code size. */ #define portPRELOAD_REGISTERS 1 /** * @brief A task is created without a secure context, and must call * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes * any secure calls. */ #define portNO_SECURE_CONTEXT 0 /*-----------------------------------------------------------*/ /** * @brief Used to catch tasks that attempt to return from their implementing * function. */ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) /** * @brief Setup the Memory Protection Unit (MPU). */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) /** * @brief Setup the Floating Point Unit (FPU). */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ /** * @brief Setup the timer to generate the tick interrupts. * * The implementation in this file is weak to allow application writers to * change the timer used to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /** * @brief Checks whether the current execution context is interrupt. * * @return pdTRUE if the current execution context is interrupt, pdFALSE * otherwise. */ BaseType_t xPortIsInsideInterrupt( void ); /** * @brief Yield the processor. */ void vPortYield( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ void vPortExitCritical( void ) PRIVILEGED_FUNCTION; /** * @brief SysTick handler. */ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; /** * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. */ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Saved as part of the task context to indicate which context the * task is using on the secure side. */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ #if ( configUSE_TICKLESS_IDLE == 1 ) /** * @brief The number of SysTick increments that make up one tick period. */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; /** * @brief The maximum number of tick periods that can be suppressed is * limited by the 24 bit resolution of the SysTick timer. */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; /** * @brief Compensate for the CPU cycles that pass while the SysTick is * stopped (low power functionality only). */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). Artificially force an assert() * to be triggered if configASSERT() is defined, then stop here so * application writers can catch the error. */ configASSERT( ulCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being * defined but never called. ulDummy is used purely to quieten other * warnings about code appearing after this function is called - making * ulDummy volatile makes the compiler think the function could return * and therefore not output an 'unreachable code' warning for code that * appears after it. */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; extern uint32_t * __unprivileged_flash_start__; extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* if defined( __ARMCC_VERSION ) */ /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; extern uint32_t __unprivileged_flash_start__[]; extern uint32_t __unprivileged_flash_end__[]; extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check that the MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* MAIR0 - Index 0. */ portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); /* MAIR0 - Index 1. */ portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* Setup privileged flash as Read Only so that privileged tasks can * read it but not modify. */ portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged flash as Read Only by both privileged and * unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged syscalls flash as Read Only by both privileged * and unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup RAM containing kernel data for privileged access only. */ portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Enable mem fault. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; /* Enable MPU with privileged background access i.e. unmapped * regions have privileged access. */ portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) { /* Enable non-secure access to the FPU. */ SecureInit_EnableNSFPUAccess(); } #endif /* configENABLE_TRUSTZONE */ /* CP10 = 11 ==> Full access to FPU i.e. both privileged and * unprivileged code should be able to access FPU. CP11 should be * programmed to the same value as CP10. */ *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) ); /* ASPEN = 1 ==> Hardware should automatically preserve floating point * context on exception entry and restore on exception return. * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ void vPortYield( void ) /* PRIVILEGED_FUNCTION */ { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ { portDISABLE_INTERRUPTS(); ulCriticalNesting++; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ { configASSERT( ulCriticalNesting ); ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { #if ( configENABLE_MPU == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ #endif /* configENABLE_MPU */ uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) uint32_t ulR0, ulR1; extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ #endif /* configENABLE_TRUSTZONE */ uint8_t ucSVCNumber; /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ ulPC = pulCallerStackAddress[ 6 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { #if ( configENABLE_TRUSTZONE == 1 ) case portSVC_ALLOCATE_SECURE_CONTEXT: /* R0 contains the stack size passed as parameter to the * vPortAllocateSecureContext function. */ ulR0 = pulCallerStackAddress[ 0 ]; #if ( configENABLE_MPU == 1 ) { /* Read the CONTROL register value. */ __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); /* The task that raised the SVC is privileged if Bit[0] * in the CONTROL register is 0. */ ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: /* R0 contains TCB being freed and R1 contains the secure * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) { /* De-prioritize the non-secure exceptions so that the * non-secure pendSV runs at the lowest priority. */ SecureInit_DePrioritizeNSExceptions(); /* Initialize the secure context management system. */ SecureContext_Init(); } #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_FPU == 1 ) { /* Setup the Floating Point Unit (FPU). */ prvSetupFPU(); } #endif /* configENABLE_FPU */ /* Setup the context of the first task so that the first task starts * executing. */ vRestoreContextOfFirstTask(); break; #if ( configENABLE_MPU == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the svc was raised from any of * the system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { vRaisePrivilege(); } break; #endif /* configENABLE_MPU */ default: /* Incorrect SVC call. */ configASSERT( pdFALSE ); } } /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #if ( configENABLE_MPU == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /* *INDENT-ON* */ { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #endif /* portPRELOAD_REGISTERS */ return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ prvSetupMPU(); } #endif /* configENABLE_MPU */ /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; /* Start the first task. */ vStartFirstTask(); /* Should never get here as the tasks will now be executing. Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* Setup MAIR0. */ xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ if( ulStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged * SRAM is already protected using an MPU region and ARMv8-M does * not allow overlapping MPU regions. */ if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) { xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; } else { /* Define the region that allows access to the stack. */ ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); } } /* User supplied configurable regions. */ for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) { /* If xRegions is NULL i.e. the task has not specified any MPU * region, the else part ensures that all the configurable MPU * regions are invalidated. */ if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) { /* Translate the generic region definition contained in xRegions * into the ARMv8 specific MPU settings that are then stored in * xMPUSettings. */ ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; /* Start address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ); /* RO/RW. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); } else { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); } /* XN. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); } /* End Address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { /* Attr1 in MAIR0 is configured as device memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; } else { /* Attr0 in MAIR0 is configured as normal memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; } } else { /* Invalidate the region. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; } lIndex++; } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. Interrupt Program * Status Register (IPSR) holds the exception number of the currently-executing * exception or zero for Thread mode.*/ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85/non_secure/portasm.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION * is defined correctly and privileged functions are placed in correct sections. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Portasm includes. */ #include "portasm.h" /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r4, [r2] \n"/* Disable MPU. */ " \n" " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r4, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r4, #4 \n"/* r4 = 4. */ " str r4, [r2] \n"/* Program RNR = 4. */ " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r3!, {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. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r4, #8 \n"/* r4 = 8. */ " str r4, [r2] \n"/* Program RNR = 8. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r3!, {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. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r4, #12 \n"/* r4 = 12. */ " str r4, [r2] \n"/* Program RNR = 12. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r3!, {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. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " str r4, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ " ldr r5, xSecureContextConst2 \n" " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ " msr control, r3 \n"/* Set this task's CONTROL value. */ " 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. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " bx r4 \n"/* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, xSecureContextConst2 \n" " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ " movs r1, #2 \n"/* r1 = 2. */ " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ " 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. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " bx r3 \n"/* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" "xSecureContextConst2: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst2: .word 0xe000ed94 \n" "xMAIR0Const2: .word 0xe000edc0 \n" "xRNRConst2: .word 0xe000ed98 \n" "xRBARConst2: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ " ite ne \n" " 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. */ " bx lr \n"/* Return. */ " \n" " .align 4 \n" ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* Read the CONTROL register. */ " bic r0, #1 \n"/* Clear the bit 0. */ " msr control, r0 \n"/* Write back the new CONTROL value. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vResetPrivilege( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " orr r0, #1 \n"/* r0 = r0 | 1. */ " msr control, r0 \n"/* CONTROL = r0. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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"/* The first entry in vector table is stack pointer. */ " msr msp, r0 \n"/* Set the MSP back to the start of the stack. */ " cpsie i \n"/* Globally enable interrupts. */ " cpsie f \n" " dsb \n" " isb \n" " svc %0 \n"/* System call to start the first task. */ " nop \n" " \n" " .align 4 \n" "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } /*-----------------------------------------------------------*/ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n"/* Return. */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); } /*-----------------------------------------------------------*/ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " msr basepri, r0 \n"/* basepri = ulMask. */ " dsb \n" " isb \n" " bx lr \n"/* Return. */ ::: "memory" ); } /*-----------------------------------------------------------*/ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" " 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 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. */ " mrs r2, psp \n"/* Read PSP in r2. */ " \n" " cbz r0, save_ns_context \n"/* No secure context to save. */ " push {r0-r2, r14} \n" " bl SecureContext_SaveContext \n"/* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r0-r3} \n"/* LR is now in 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. */ " 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" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB.*/ #if ( configENABLE_MPU == 1 ) " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ " str r2, [r1] \n"/* Save the new top of stack in TCB. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r3, control \n"/* r3 = CONTROL. */ " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ " 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. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ " b select_next_task \n" " \n" " save_ns_context: \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ #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. */ " it eq \n" " vstmdbeq r2!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ " str r2, [r1] \n"/* Save the new top of stack in TCB. */ " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r3, control \n"/* r3 = CONTROL. */ " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ " subs r2, r2, #16 \n"/* r2 = r2 - 16. */ " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ " 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. */ " adds r2, r2, #12 \n"/* r2 = r2 + 12. */ " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " subs r2, r2, #12 \n"/* r2 = r2 - 12. */ " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ " \n" " select_next_task: \n" " mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" " mov r0, #0 \n"/* r0 = 0. */ " msr basepri, r0 \n"/* Enable interrupts. */ " \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r4, [r3] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ " str r4, [r3] \n"/* Program MAIR0. */ " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ " movs r4, #4 \n"/* r4 = 4. */ " str r4, [r3] \n"/* Program RNR = 4. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ " movs r4, #8 \n"/* r4 = 8. */ " str r4, [r3] \n"/* Program RNR = 8. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ " movs r4, #12 \n"/* r4 = 12. */ " str r4, [r3] \n"/* Program RNR = 12. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " str r4, [r3] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ " mov lr, r4 \n"/* LR = r4. */ " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( 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. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " push {r2, r4} \n" " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r2, r4} \n" " 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. */ " 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. */ " bx lr \n" #else /* configENABLE_MPU */ " 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. */ " mov lr, r4 \n"/* LR = r4. */ " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( 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. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " push {r2, r4} \n" " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r2, r4} \n" " 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. */ " 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. */ " bx lr \n" #endif /* configENABLE_MPU */ " \n" " restore_ns_context: \n" " ldmia r2!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */ #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. */ " it eq \n" " vldmiaeq r2!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ " msr psp, r2 \n"/* Remember the new top of stack for the task. */ " bx lr \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" "xSecureContextConst: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst: .word 0xe000ed94 \n" "xMAIR0Const: .word 0xe000edc0 \n" "xRNRConst: .word 0xe000ed98 \n" "xRBARConst: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } /*-----------------------------------------------------------*/ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " tst lr, #4 \n" " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" " ldr r1, svchandler_address_const \n" " bx r1 \n" " \n" " .align 4 \n" "svchandler_address_const: .word vPortSVCHandler_C \n" ); } /*-----------------------------------------------------------*/ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " svc %0 \n"/* Secure context is allocated in the supervisor call. */ " bx lr \n"/* Return. */ ::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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. */ " cmp r1, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */ " it ne \n" " svcne %0 \n"/* Secure context is freed in the supervisor call. */ " bx lr \n"/* Return. */ ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85/non_secure/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORT_ASM_H__ #define __PORT_ASM_H__ /* Scheduler includes. */ #include "FreeRTOS.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /** * @brief Restore the context of the first task so that the first task starts * executing. */ void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * * @note This is a privileged function and should only be called from the kenrel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Starts the first task. */ void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Disables interrupts. */ uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Enables interrupts. */ void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief PendSV Exception handler. */ void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief SVC Handler. */ void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Allocate a Secure context for the calling task. * * @param[in] ulSecureStackSize The size of the stack to be allocated on the * secure side for the calling task. */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); /** * @brief Free the task's secure context. * * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. */ void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* __PORT_ASM_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85/non_secure/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_MVE #error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE. #endif /* configENABLE_MVE */ /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M85" #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACROCOMMON_H #define PORTMACROCOMMON_H #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_FPU #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. #endif /* configENABLE_FPU */ #ifndef configENABLE_MPU #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. #endif /* configENABLE_MPU */ #ifndef configENABLE_TRUSTZONE #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ /** * @brief Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif #define portHAS_STACK_OVERFLOW_CHECKING 1 /*-----------------------------------------------------------*/ /** * @brief Extern declarations. */ extern BaseType_t xPortIsInsideInterrupt( void ); extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; #if ( configENABLE_TRUSTZONE == 1 ) extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_MPU == 1 ) extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief MPU specific constants. */ #if ( configENABLE_MPU == 1 ) #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #else #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* MPU regions. */ #define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_RAM_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ /* Device memory attributes used in MPU_MAIR registers. * * 8-bit values encoded as follows: * Bit[7:4] - 0000 - Device Memory * Bit[3:2] - 00 --> Device-nGnRnE * 01 --> Device-nGnRE * 10 --> Device-nGRE * 11 --> Device-GRE * Bit[1:0] - 00, Reserved. */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ /* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ /* Attributes used in MPU_RBAR registers. */ #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ /** * @brief Settings to define an MPU region. */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */ } MPURegionSettings_t; /** * @brief MPU settings as stored in the TCB. */ typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ } xMPU_SETTINGS; /*-----------------------------------------------------------*/ /** * @brief SVC numbers. */ #define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 /*-----------------------------------------------------------*/ /** * @brief Scheduler utilities. */ #define portYIELD() vPortYield() #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /** * @brief Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /** * @brief Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Allocate a secure context for the task. * * 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 context before it calls any secure function. * * @param[in] ulSecureStackSize The size of the secure stack to be allocated. */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) /** * @brief Called when a task is deleted to delete the task's secure context, * if it has one. * * @param[in] pxTCB The TCB of the task being deleted. */ #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. * * 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, * the privilege is not raised. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() #else #define portIS_PRIVILEGED() #define portRAISE_PRIVILEGE() #define portRESET_PRIVILEGE() #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief Barriers. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACROCOMMON_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85/secure/secure_context.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Secure context includes. */ #include "secure_context.h" /* Secure heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief CONTROL value for privileged tasks. * * Bit[0] - 0 --> Thread mode is privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_PRIVILEGED 0x02 /** * @brief CONTROL value for un-privileged tasks. * * Bit[0] - 1 --> Thread mode is un-privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 /** * @brief Size of stack seal values in bytes. */ #define securecontextSTACK_SEAL_SIZE 8 /** * @brief Stack seal value as recommended by ARM. */ #define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5 /** * @brief Maximum number of secure contexts. */ #ifndef secureconfigMAX_SECURE_CONTEXTS #define secureconfigMAX_SECURE_CONTEXTS 8UL #endif /*-----------------------------------------------------------*/ /** * @brief Pre-allocated array of secure contexts. */ SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ]; /*-----------------------------------------------------------*/ /** * @brief Get a free secure context for a task from the secure context pool (xSecureContexts). * * This function ensures that only one secure context is allocated for a task. * * @param[in] pvTaskHandle The task handle for which the secure context is allocated. * * @return Index of a free secure context in the xSecureContexts array. */ static uint32_t ulGetSecureContext( void * pvTaskHandle ); /** * @brief Return the secure context to the secure context pool (xSecureContexts). * * @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array. */ static void vReturnSecureContext( uint32_t ulSecureContextIndex ); /* These are implemented in assembly. */ extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ); extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ); /*-----------------------------------------------------------*/ static uint32_t ulGetSecureContext( void * pvTaskHandle ) { /* Start with invalid index. */ uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) && ( xSecureContexts[ i ].pucStackLimit == NULL ) && ( xSecureContexts[ i ].pucStackStart == NULL ) && ( xSecureContexts[ i ].pvTaskHandle == NULL ) && ( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = i; } else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle ) { /* A task can only have one secure context. Do not allocate a second * context for the same task. */ ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; break; } } return ulSecureContextIndex; } /*-----------------------------------------------------------*/ static void vReturnSecureContext( uint32_t ulSecureContextIndex ) { xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) { uint32_t ulIPSR, i; static uint32_t ulSecureContextsInitialized = 0; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) ) { /* Ensure to initialize secure contexts only once. */ ulSecureContextsInitialized = 1; /* No stack for thread mode until a task's context is loaded. */ secureportSET_PSPLIM( securecontextNO_STACK ); secureportSET_PSP( securecontextNO_STACK ); /* Initialize all secure contexts. */ for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { xSecureContexts[ i ].pucCurrentStackPointer = NULL; xSecureContexts[ i ].pucStackLimit = NULL; xSecureContexts[ i ].pucStackStart = NULL; xSecureContexts[ i ].pvTaskHandle = NULL; } #if ( configENABLE_MPU == 1 ) { /* Configure thread mode to use PSP and to be unprivileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED ); } #else /* configENABLE_MPU */ { /* Configure thread mode to use PSP and to be privileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED ); } #endif /* configENABLE_MPU */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ) #else /* configENABLE_MPU */ secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ) #endif /* configENABLE_MPU */ { uint8_t * pucStackMemory = NULL; uint8_t * pucStackLimit; uint32_t ulIPSR, ulSecureContextIndex; SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID; #if ( configENABLE_MPU == 1 ) uint32_t * pulCurrentStackPointer = NULL; #endif /* configENABLE_MPU */ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit * Register (PSPLIM) value. */ secureportREAD_IPSR( ulIPSR ); secureportREAD_PSPLIM( pucStackLimit ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. * Also do nothing, if a secure context us already loaded. PSPLIM is set to * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { /* Ontain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space. */ pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE ); if( pucStackMemory != NULL ) { /* Since stack grows down, the starting point will be the last * location. Note that this location is next to the last * allocated byte for stack (excluding the space for seal values) * because the hardware decrements the stack pointer before * writing i.e. if stack pointer is 0x2, a push operation will * decrement the stack pointer to 0x1 and then write at 0x1. */ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize; /* Seal the created secure process stack. */ *( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE; *( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE; /* The stack cannot go beyond this location. This value is * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle; #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 ) { *( 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 /* configENABLE_MPU */ { /* Current SP is set to the starting of the stack. This * value programmed in the PSP register on context switch. */ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart; } #endif /* configENABLE_MPU */ /* Ensure to never return 0 as a valid context handle. */ xSecureContextHandle = ulSecureContextIndex + 1UL; } } } return xSecureContextHandle; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint32_t ulIPSR, ulSecureContextIndex; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* Only free if a valid context handle is passed. */ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; /* Ensure that the secure context being deleted is associated with * the task. */ if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) { /* Free the stack space. */ vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); /* Return the secure context back to the free secure contexts pool. */ vReturnSecureContext( ulSecureContextIndex ); } } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that no secure context is loaded and the task is loading it's * own context. */ if( ( pucStackLimit == securecontextNO_STACK ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that task's context is loaded and the task is saving it's own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85/secure/secure_context.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_CONTEXT_H__ #define __SECURE_CONTEXT_H__ /* Standard includes. */ #include /* FreeRTOS includes. */ #include "FreeRTOSConfig.h" /** * @brief PSP value when no secure context is loaded. */ #define securecontextNO_STACK 0x0 /** * @brief Invalid context ID. */ #define securecontextINVALID_CONTEXT_ID 0UL /*-----------------------------------------------------------*/ /** * @brief Structure to represent a secure context. * * @note Since stack grows down, pucStackStart is the highest address while * pucStackLimit is the first address of the allocated memory. */ typedef struct SecureContext { uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */ uint8_t * pucStackStart; /**< First location of the stack memory. */ void * pvTaskHandle; /**< Task handle of the task this context is associated with. */ } SecureContext_t; /*-----------------------------------------------------------*/ /** * @brief Opaque handle for a secure context. */ typedef uint32_t SecureContextHandle_t; /*-----------------------------------------------------------*/ /** * @brief Initializes the secure context management system. * * PSP is set to NULL and therefore a task must allocate and load a context * before calling any secure side function in the thread mode. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureContext_Init( void ); /** * @brief Allocates a context on the secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] ulSecureStackSize Size of the stack to allocate on secure side. * @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise. * * @return Opaque context handle if context is successfully allocated, NULL * otherwise. */ #if ( configENABLE_MPU == 1 ) SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ); #else /* configENABLE_MPU */ SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ); #endif /* configENABLE_MPU */ /** * @brief Frees the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the * context to be freed. */ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Loads the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be loaded. */ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Saves the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be saved. */ void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); #endif /* __SECURE_CONTEXT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85/secure/secure_context_port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Secure context includes. */ #include "secure_context.h" /* Secure port macros. */ #include "secure_port_macros.h" void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) { /* pxSecureContext value is in r0. */ __asm volatile ( " .syntax unified \n" " \n" " mrs r1, ipsr \n" /* r1 = IPSR. */ " cbz r1, load_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */ " ldmia r0!, {r1, r2} \n" /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */ " \n" #if ( configENABLE_MPU == 1 ) " ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */ " msr control, r3 \n" /* CONTROL = r3. */ #endif /* configENABLE_MPU */ " \n" " msr psplim, r2 \n" /* PSPLIM = r2. */ " msr psp, r1 \n" /* PSP = r1. */ " \n" " load_ctx_therad_mode: \n" " bx lr \n" " \n" ::: "r0", "r1", "r2" ); } /*-----------------------------------------------------------*/ void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) { /* pxSecureContext value is in r0. */ __asm volatile ( " .syntax unified \n" " \n" " mrs r1, ipsr \n" /* r1 = IPSR. */ " cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */ " mrs r1, psp \n" /* r1 = PSP. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " vstmdb r1!, {s0} \n" /* Trigger the deferred stacking of FPU registers. */ " vldmia r1!, {s0} \n" /* Nullify the effect of the previous statement. */ #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" #if ( configENABLE_MPU == 1 ) " mrs r2, control \n" /* r2 = CONTROL. */ " stmdb r1!, {r2} \n" /* Store CONTROL value on the stack. */ #endif /* configENABLE_MPU */ " \n" " str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ " movs r1, %0 \n" /* r1 = securecontextNO_STACK. */ " msr psplim, r1 \n" /* PSPLIM = securecontextNO_STACK. */ " msr psp, r1 \n" /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */ " \n" " save_ctx_therad_mode: \n" " bx lr \n" " \n" ::"i" ( securecontextNO_STACK ) : "r1", "memory" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85/secure/secure_heap.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure context heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Total heap size. */ #ifndef secureconfigTOTAL_HEAP_SIZE #define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) ) #endif /* No test marker by default. */ #ifndef mtCOVERAGE_TEST_MARKER #define mtCOVERAGE_TEST_MARKER() #endif /* No tracing by default. */ #ifndef traceMALLOC #define traceMALLOC( pvReturn, xWantedSize ) #endif /* No tracing by default. */ #ifndef traceFREE #define traceFREE( pv, xBlockSize ) #endif /* Block sizes must not get too small. */ #define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) /* Assumes 8bit bytes! */ #define secureheapBITS_PER_BYTE ( ( size_t ) 8 ) /*-----------------------------------------------------------*/ /* Allocate the memory for the heap. */ #if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) /* The application writer has already defined the array used for the RTOS * heap - probably so it can be placed in a special segment or address. */ extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #else /* configAPPLICATION_ALLOCATED_HEAP */ static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #endif /* configAPPLICATION_ALLOCATED_HEAP */ /** * @brief The linked list structure. * * This is used to link free blocks in order of their memory address. */ typedef struct A_BLOCK_LINK { struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */ size_t xBlockSize; /**< The size of the free block. */ } BlockLink_t; /*-----------------------------------------------------------*/ /** * @brief Called automatically to setup the required heap structures the first * time pvPortMalloc() is called. */ static void prvHeapInit( void ); /** * @brief Inserts a block of memory that is being freed into the correct * position in the list of free memory blocks. * * The block being freed will be merged with the block in front it and/or the * block behind it if the memory blocks are adjacent to each other. * * @param[in] pxBlockToInsert The block being freed. */ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ); /*-----------------------------------------------------------*/ /** * @brief The size of the structure placed at the beginning of each allocated * memory block must by correctly byte aligned. */ static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); /** * @brief Create a couple of list links to mark the start and end of the list. */ static BlockLink_t xStart; static BlockLink_t * pxEnd = NULL; /** * @brief Keeps track of the number of free bytes remaining, but says nothing * about fragmentation. */ static size_t xFreeBytesRemaining = 0U; static size_t xMinimumEverFreeBytesRemaining = 0U; /** * @brief Gets set to the top bit of an size_t type. * * When this bit in the xBlockSize member of an BlockLink_t structure is set * then the block belongs to the application. When the bit is free the block is * still part of the free heap space. */ static size_t xBlockAllocatedBit = 0; /*-----------------------------------------------------------*/ static void prvHeapInit( void ) { BlockLink_t * pxFirstFreeBlock; uint8_t * pucAlignedHeap; size_t uxAddress; size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE; /* Ensure the heap starts on a correctly aligned boundary. */ uxAddress = ( size_t ) ucHeap; if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 ) { uxAddress += ( secureportBYTE_ALIGNMENT - 1 ); uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; } pucAlignedHeap = ( uint8_t * ) uxAddress; /* xStart is used to hold a pointer to the first item in the list of free * blocks. The void cast is used to prevent compiler warnings. */ xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; xStart.xBlockSize = ( size_t ) 0; /* pxEnd is used to mark the end of the list of free blocks and is inserted * at the end of the heap space. */ uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; uxAddress -= xHeapStructSize; uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); pxEnd = ( void * ) uxAddress; pxEnd->xBlockSize = 0; pxEnd->pxNextFreeBlock = NULL; /* To start with there is a single free block that is sized to take up the * entire heap space, minus the space taken by pxEnd. */ pxFirstFreeBlock = ( void * ) pucAlignedHeap; pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; pxFirstFreeBlock->pxNextFreeBlock = pxEnd; /* Only one block exists - and it covers the entire usable heap space. */ xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; /* Work out the position of the top bit in a size_t variable. */ xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 ); } /*-----------------------------------------------------------*/ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) { BlockLink_t * pxIterator; uint8_t * puc; /* Iterate through the list until a block is found that has a higher address * than the block being inserted. */ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) { /* Nothing to do here, just iterate to the right position. */ } /* Do the block being inserted, and the block it is being inserted after * make a contiguous block of memory? */ puc = ( uint8_t * ) pxIterator; if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) { pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; pxBlockToInsert = pxIterator; } else { mtCOVERAGE_TEST_MARKER(); } /* Do the block being inserted, and the block it is being inserted before * make a contiguous block of memory? */ puc = ( uint8_t * ) pxBlockToInsert; if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) { if( pxIterator->pxNextFreeBlock != pxEnd ) { /* Form one big block from the two blocks. */ pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; } else { pxBlockToInsert->pxNextFreeBlock = pxEnd; } } else { pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } /* If the block being inserted plugged a gab, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ if( pxIterator != pxBlockToInsert ) { pxIterator->pxNextFreeBlock = pxBlockToInsert; } else { mtCOVERAGE_TEST_MARKER(); } } /*-----------------------------------------------------------*/ void * pvPortMalloc( size_t xWantedSize ) { BlockLink_t * pxBlock; BlockLink_t * pxPreviousBlock; BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ if( pxEnd == NULL ) { prvHeapInit(); } else { mtCOVERAGE_TEST_MARKER(); } /* Check the requested block size is not so large that the top bit is set. * The top bit of the block size member of the BlockLink_t structure is used * to determine who owns the block - the application or the kernel, so it * must be free. */ if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) { /* The wanted size is increased so it can contain a BlockLink_t * structure in addition to the requested amount of bytes. */ if( xWantedSize > 0 ) { xWantedSize += xHeapStructSize; /* Ensure that blocks are always aligned to the required number of * bytes. */ if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 ) { /* Byte alignment required. */ xWantedSize += ( secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) ); secureportASSERT( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) == 0 ); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) { /* Traverse the list from the start (lowest address) block until * one of adequate size is found. */ pxPreviousBlock = &xStart; pxBlock = xStart.pxNextFreeBlock; while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) { pxPreviousBlock = pxBlock; pxBlock = pxBlock->pxNextFreeBlock; } /* If the end marker was reached then a block of adequate size was * not found. */ if( pxBlock != pxEnd ) { /* Return the memory space pointed to - jumping over the * BlockLink_t structure at its start. */ pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); /* This block is being returned for use so must be taken out * of the list of free blocks. */ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; /* If the block is larger than required it can be split into * two. */ if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE ) { /* This block is to be split into two. Create a new * block following the number of bytes requested. The void * cast is used to prevent byte alignment warnings from the * compiler. */ pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 ); /* Calculate the sizes of two blocks split from the single * block. */ pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; pxBlock->xBlockSize = xWantedSize; /* Insert the new block into the list of free blocks. */ prvInsertBlockIntoFreeList( pxNewBlockLink ); } else { mtCOVERAGE_TEST_MARKER(); } xFreeBytesRemaining -= pxBlock->xBlockSize; if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) { xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; } else { mtCOVERAGE_TEST_MARKER(); } /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ pxBlock->xBlockSize |= xBlockAllocatedBit; pxBlock->pxNextFreeBlock = NULL; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } traceMALLOC( pvReturn, xWantedSize ); #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { extern void vApplicationMallocFailedHook( void ); vApplicationMallocFailedHook(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */ secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 ); return pvReturn; } /*-----------------------------------------------------------*/ void vPortFree( void * pv ) { uint8_t * puc = ( uint8_t * ) pv; BlockLink_t * pxLink; if( pv != NULL ) { /* The memory being freed will have an BlockLink_t structure immediately * before it. */ puc -= xHeapStructSize; /* This casting is to keep the compiler from issuing warnings. */ pxLink = ( void * ) puc; /* Check the block is actually allocated. */ secureportASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); secureportASSERT( pxLink->pxNextFreeBlock == NULL ); if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) { if( pxLink->pxNextFreeBlock == NULL ) { /* The block is being returned to the heap - it is no longer * allocated. */ pxLink->xBlockSize &= ~xBlockAllocatedBit; secureportDISABLE_NON_SECURE_INTERRUPTS(); { /* Add this block to the list of free blocks. */ xFreeBytesRemaining += pxLink->xBlockSize; traceFREE( pv, pxLink->xBlockSize ); prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); } secureportENABLE_NON_SECURE_INTERRUPTS(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } } /*-----------------------------------------------------------*/ size_t xPortGetFreeHeapSize( void ) { return xFreeBytesRemaining; } /*-----------------------------------------------------------*/ size_t xPortGetMinimumEverFreeHeapSize( void ) { return xMinimumEverFreeBytesRemaining; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85/secure/secure_heap.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_HEAP_H__ #define __SECURE_HEAP_H__ /* Standard includes. */ #include /** * @brief Allocates memory from heap. * * @param[in] xWantedSize The size of the memory to be allocated. * * @return Pointer to the memory region if the allocation is successful, NULL * otherwise. */ void * pvPortMalloc( size_t xWantedSize ); /** * @brief Frees the previously allocated memory. * * @param[in] pv Pointer to the memory to be freed. */ void vPortFree( void * pv ); /** * @brief Get the free heap size. * * @return Free heap size. */ size_t xPortGetFreeHeapSize( void ); /** * @brief Get the minimum ever free heap size. * * @return Minimum ever free heap size. */ size_t xPortGetMinimumEverFreeHeapSize( void ); #endif /* __SECURE_HEAP_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85/secure/secure_init.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure init includes. */ #include "secure_init.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Constants required to manipulate the SCB. */ #define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */ #define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL ) #define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS ) #define secureinitSCB_AIRCR_PRIS_POS ( 14UL ) #define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS ) /** * @brief Constants required to manipulate the FPU. */ #define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define secureinitFPCCR_LSPENS_POS ( 29UL ) #define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS ) #define secureinitFPCCR_TS_POS ( 26UL ) #define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS ) #define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */ #define secureinitNSACR_CP10_POS ( 10UL ) #define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS ) #define secureinitNSACR_CP11_POS ( 11UL ) #define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS ) /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { *( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) | ( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) | ( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK ); } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* CP10 = 1 ==> Non-secure access to the Floating Point Unit is * permitted. CP11 should be programmed to the same value as CP10. */ *( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK ); /* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures * that we can enable/disable lazy stacking in port.c file. */ *( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK ); /* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP * registers (S16-S31) are also pushed to stack on exception entry and * restored on exception return. */ *( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK ); } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85/secure/secure_init.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_INIT_H__ #define __SECURE_INIT_H__ /** * @brief De-prioritizes the non-secure exceptions. * * This is needed to ensure that the non-secure PendSV runs at the lowest * priority. Context switch is done in the non-secure PendSV handler. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_DePrioritizeNSExceptions( void ); /** * @brief Sets up the Floating Point Unit (FPU) for Non-Secure access. * * Also sets FPCCR.TS=1 to ensure that the content of the Floating Point * Registers are not leaked to the non-secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_EnableNSFPUAccess( void ); #endif /* __SECURE_INIT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85/secure/secure_port_macros.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_PORT_MACROS_H__ #define __SECURE_PORT_MACROS_H__ /** * @brief Byte alignment requirements. */ #define secureportBYTE_ALIGNMENT 8 #define secureportBYTE_ALIGNMENT_MASK ( 0x0007 ) /** * @brief Macro to declare a function as non-secure callable. */ #if defined( __IAR_SYSTEMS_ICC__ ) #define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root #else #define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) ) #endif /** * @brief Set the secure PRIMASK value. */ #define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Set the non-secure PRIMASK value. */ #define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Read the PSP value in the given variable. */ #define secureportREAD_PSP( pucOutCurrentStackPointer ) \ __asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) ) /** * @brief Set the PSP to the given value. */ #define secureportSET_PSP( pucCurrentStackPointer ) \ __asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) ) /** * @brief Read the PSPLIM value in the given variable. */ #define secureportREAD_PSPLIM( pucOutStackLimit ) \ __asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) ) /** * @brief Set the PSPLIM to the given value. */ #define secureportSET_PSPLIM( pucStackLimit ) \ __asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) ) /** * @brief Set the NonSecure MSP to the given value. */ #define secureportSET_MSP_NS( pucMainStackPointer ) \ __asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) ) /** * @brief Set the CONTROL register to the given value. */ #define secureportSET_CONTROL( ulControl ) \ __asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" ) /** * @brief Read the Interrupt Program Status Register (IPSR) value in the given * variable. */ #define secureportREAD_IPSR( ulIPSR ) \ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) ) /** * @brief PRIMASK value to enable interrupts. */ #define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0 /** * @brief PRIMASK value to disable interrupts. */ #define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1 /** * @brief Disable secure interrupts. */ #define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Disable non-secure interrupts. * * This effectively disables context switches. */ #define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Enable non-secure interrupts. */ #define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL ) /** * @brief Assert definition. */ #define secureportASSERT( x ) \ if( ( x ) == 0 ) \ { \ secureportDISABLE_SECURE_INTERRUPTS(); \ secureportDISABLE_NON_SECURE_INTERRUPTS(); \ for( ; ; ) {; } \ } #endif /* __SECURE_PORT_MACROS_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85_NTZ/non_secure/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /* Portasm includes. */ #include "portasm.h" #if ( configENABLE_TRUSTZONE == 1 ) /* Secure components includes. */ #include "secure_context.h" #include "secure_init.h" #endif /* configENABLE_TRUSTZONE */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /** * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS * on the secure side. The following are the valid configuration seetings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 * * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 * * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 */ #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. #endif /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the SCB. */ #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the FPU. */ #define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) #define portMPU_RLAR_REGION_ENABLE ( 1UL ) /* Enable privileged access to unmapped region. */ #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /*-----------------------------------------------------------*/ /** * @brief The maximum 24-bit number. * * It is needed because the systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /** * @brief A fiddle factor to estimate the number of SysTick counts that would * have occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) /** * @brief Initial EXC_RETURN value. * * FF FF FF FD * 1111 1111 1111 1111 1111 1111 1111 1101 * * Bit[6] - 1 --> The exception was taken from the Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 1 --> The exception was taken to the Secure state. */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else /** * @brief Initial EXC_RETURN value. * * FF FF FF BC * 1111 1111 1111 1111 1111 1111 1011 1100 * * Bit[6] - 0 --> The exception was taken from the Non-Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 0 --> The exception was taken to the Non-Secure state. */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ /** * @brief CONTROL register privileged bit mask. * * Bit[0] in CONTROL register tells the privilege: * Bit[0] = 0 ==> The task is privileged. * Bit[0] = 1 ==> The task is not privileged. */ #define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) /** * @brief Initial CONTROL register values. */ #define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) #define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) /** * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /** * @brief 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /** * @brief If portPRELOAD_REGISTERS then registers will be given an initial value * when a task is created. This helps in debugging at the cost of code size. */ #define portPRELOAD_REGISTERS 1 /** * @brief A task is created without a secure context, and must call * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes * any secure calls. */ #define portNO_SECURE_CONTEXT 0 /*-----------------------------------------------------------*/ /** * @brief Used to catch tasks that attempt to return from their implementing * function. */ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) /** * @brief Setup the Memory Protection Unit (MPU). */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) /** * @brief Setup the Floating Point Unit (FPU). */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ /** * @brief Setup the timer to generate the tick interrupts. * * The implementation in this file is weak to allow application writers to * change the timer used to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /** * @brief Checks whether the current execution context is interrupt. * * @return pdTRUE if the current execution context is interrupt, pdFALSE * otherwise. */ BaseType_t xPortIsInsideInterrupt( void ); /** * @brief Yield the processor. */ void vPortYield( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ void vPortExitCritical( void ) PRIVILEGED_FUNCTION; /** * @brief SysTick handler. */ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; /** * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. */ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Saved as part of the task context to indicate which context the * task is using on the secure side. */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ #if ( configUSE_TICKLESS_IDLE == 1 ) /** * @brief The number of SysTick increments that make up one tick period. */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; /** * @brief The maximum number of tick periods that can be suppressed is * limited by the 24 bit resolution of the SysTick timer. */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; /** * @brief Compensate for the CPU cycles that pass while the SysTick is * stopped (low power functionality only). */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). Artificially force an assert() * to be triggered if configASSERT() is defined, then stop here so * application writers can catch the error. */ configASSERT( ulCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being * defined but never called. ulDummy is used purely to quieten other * warnings about code appearing after this function is called - making * ulDummy volatile makes the compiler think the function could return * and therefore not output an 'unreachable code' warning for code that * appears after it. */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; extern uint32_t * __unprivileged_flash_start__; extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* if defined( __ARMCC_VERSION ) */ /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; extern uint32_t __unprivileged_flash_start__[]; extern uint32_t __unprivileged_flash_end__[]; extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check that the MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* MAIR0 - Index 0. */ portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); /* MAIR0 - Index 1. */ portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* Setup privileged flash as Read Only so that privileged tasks can * read it but not modify. */ portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged flash as Read Only by both privileged and * unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged syscalls flash as Read Only by both privileged * and unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup RAM containing kernel data for privileged access only. */ portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Enable mem fault. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; /* Enable MPU with privileged background access i.e. unmapped * regions have privileged access. */ portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) { /* Enable non-secure access to the FPU. */ SecureInit_EnableNSFPUAccess(); } #endif /* configENABLE_TRUSTZONE */ /* CP10 = 11 ==> Full access to FPU i.e. both privileged and * unprivileged code should be able to access FPU. CP11 should be * programmed to the same value as CP10. */ *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) ); /* ASPEN = 1 ==> Hardware should automatically preserve floating point * context on exception entry and restore on exception return. * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ void vPortYield( void ) /* PRIVILEGED_FUNCTION */ { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ { portDISABLE_INTERRUPTS(); ulCriticalNesting++; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ { configASSERT( ulCriticalNesting ); ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { #if ( configENABLE_MPU == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ #endif /* configENABLE_MPU */ uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) uint32_t ulR0, ulR1; extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ #endif /* configENABLE_TRUSTZONE */ uint8_t ucSVCNumber; /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ ulPC = pulCallerStackAddress[ 6 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { #if ( configENABLE_TRUSTZONE == 1 ) case portSVC_ALLOCATE_SECURE_CONTEXT: /* R0 contains the stack size passed as parameter to the * vPortAllocateSecureContext function. */ ulR0 = pulCallerStackAddress[ 0 ]; #if ( configENABLE_MPU == 1 ) { /* Read the CONTROL register value. */ __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); /* The task that raised the SVC is privileged if Bit[0] * in the CONTROL register is 0. */ ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: /* R0 contains TCB being freed and R1 contains the secure * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) { /* De-prioritize the non-secure exceptions so that the * non-secure pendSV runs at the lowest priority. */ SecureInit_DePrioritizeNSExceptions(); /* Initialize the secure context management system. */ SecureContext_Init(); } #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_FPU == 1 ) { /* Setup the Floating Point Unit (FPU). */ prvSetupFPU(); } #endif /* configENABLE_FPU */ /* Setup the context of the first task so that the first task starts * executing. */ vRestoreContextOfFirstTask(); break; #if ( configENABLE_MPU == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the svc was raised from any of * the system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { vRaisePrivilege(); } break; #endif /* configENABLE_MPU */ default: /* Incorrect SVC call. */ configASSERT( pdFALSE ); } } /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #if ( configENABLE_MPU == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /* *INDENT-ON* */ { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #endif /* portPRELOAD_REGISTERS */ return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ prvSetupMPU(); } #endif /* configENABLE_MPU */ /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; /* Start the first task. */ vStartFirstTask(); /* Should never get here as the tasks will now be executing. Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* Setup MAIR0. */ xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ if( ulStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged * SRAM is already protected using an MPU region and ARMv8-M does * not allow overlapping MPU regions. */ if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) { xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; } else { /* Define the region that allows access to the stack. */ ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); } } /* User supplied configurable regions. */ for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) { /* If xRegions is NULL i.e. the task has not specified any MPU * region, the else part ensures that all the configurable MPU * regions are invalidated. */ if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) { /* Translate the generic region definition contained in xRegions * into the ARMv8 specific MPU settings that are then stored in * xMPUSettings. */ ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; /* Start address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ); /* RO/RW. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); } else { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); } /* XN. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); } /* End Address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { /* Attr1 in MAIR0 is configured as device memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; } else { /* Attr0 in MAIR0 is configured as normal memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; } } else { /* Invalidate the region. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; } lIndex++; } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. Interrupt Program * Status Register (IPSR) holds the exception number of the currently-executing * exception or zero for Thread mode.*/ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION * is defined correctly and privileged functions are placed in correct sections. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Portasm includes. */ #include "portasm.h" /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r4, [r2] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r3, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #4 \n"/* r3 = 4. */ " str r3, [r2] \n"/* Program RNR = 4. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #8 \n"/* r3 = 8. */ " str r3, [r2] \n"/* Program RNR = 8. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #12 \n"/* r3 = 12. */ " str r3, [r2] \n"/* Program RNR = 12. */ " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " str r4, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ " msr control, r2 \n"/* Set this task's CONTROL value. */ " 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. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " bx r3 \n"/* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ " movs r1, #2 \n"/* r1 = 2. */ " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ " 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. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " bx r2 \n"/* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst2: .word 0xe000ed94 \n" "xMAIR0Const2: .word 0xe000edc0 \n" "xRNRConst2: .word 0xe000ed98 \n" "xRBARConst2: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ " ite ne \n" " 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. */ " bx lr \n"/* Return. */ " \n" " .align 4 \n" ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* Read the CONTROL register. */ " bic r0, #1 \n"/* Clear the bit 0. */ " msr control, r0 \n"/* Write back the new CONTROL value. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vResetPrivilege( void ) /* __attribute__ (( naked )) */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, control \n"/* r0 = CONTROL. */ " orr r0, #1 \n"/* r0 = r0 | 1. */ " msr control, r0 \n"/* CONTROL = r0. */ " bx lr \n"/* Return to the caller. */ ::: "r0", "memory" ); } /*-----------------------------------------------------------*/ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " 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"/* The first entry in vector table is stack pointer. */ " msr msp, r0 \n"/* Set the MSP back to the start of the stack. */ " cpsie i \n"/* Globally enable interrupts. */ " cpsie f \n" " dsb \n" " isb \n" " svc %0 \n"/* System call to start the first task. */ " nop \n" " \n" " .align 4 \n" "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } /*-----------------------------------------------------------*/ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n"/* Return. */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ); } /*-----------------------------------------------------------*/ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " msr basepri, r0 \n"/* basepri = ulMask. */ " dsb \n" " isb \n" " bx lr \n"/* Return. */ ::: "memory" ); } /*-----------------------------------------------------------*/ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " mrs r0, psp \n"/* Read PSP in r0. */ #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. */ " it eq \n" " vstmdbeq r0!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) " mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r2, control \n"/* r2 = CONTROL. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r1-r11} \n"/* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ #else /* configENABLE_MPU */ " mrs r2, psplim \n"/* r2 = PSPLIM. */ " 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. */ #endif /* configENABLE_MPU */ " \n" " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " str r0, [r1] \n"/* Save the new top of stack in TCB. */ " \n" " mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" " mov r0, #0 \n"/* r0 = 0. */ " msr basepri, r0 \n"/* Enable interrupts. */ " \n" " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( 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. */ " \n" #if ( configENABLE_MPU == 1 ) " dmb \n"/* Complete outstanding transfers before disabling MPU. */ " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r4, [r2] \n"/* Disable MPU. */ " \n" " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r3, [r2] \n"/* Program MAIR0. */ " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #4 \n"/* r3 = 4. */ " str r3, [r2] \n"/* Program RNR = 4. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #8 \n"/* r3 = 8. */ " str r3, [r2] \n"/* Program RNR = 8. */ " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " movs r3, #12 \n"/* r3 = 12. */ " str r3, [r2] \n"/* Program RNR = 12. */ " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldmia r1!, {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. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " str r4, [r2] \n"/* Enable MPU. */ " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) " ldmia r0!, {r1-r11} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ #else /* configENABLE_MPU */ " ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #endif /* configENABLE_MPU */ " \n" #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. */ " it eq \n" " vldmiaeq r0!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" #if ( configENABLE_MPU == 1 ) " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ " msr control, r2 \n"/* Restore the CONTROL register value for the task. */ #else /* configENABLE_MPU */ " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ #endif /* configENABLE_MPU */ " msr psp, r0 \n"/* Remember the new top of stack for the task. */ " bx r3 \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" #if ( configENABLE_MPU == 1 ) "xMPUCTRLConst: .word 0xe000ed94 \n" "xMAIR0Const: .word 0xe000edc0 \n" "xRNRConst: .word 0xe000ed98 \n" "xRBARConst: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } /*-----------------------------------------------------------*/ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( " .syntax unified \n" " \n" " tst lr, #4 \n" " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" " ldr r1, svchandler_address_const \n" " bx r1 \n" " \n" " .align 4 \n" "svchandler_address_const: .word vPortSVCHandler_C \n" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORT_ASM_H__ #define __PORT_ASM_H__ /* Scheduler includes. */ #include "FreeRTOS.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /** * @brief Restore the context of the first task so that the first task starts * executing. */ void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * * @note This is a privileged function and should only be called from the kenrel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Starts the first task. */ void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Disables interrupts. */ uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Enables interrupts. */ void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief PendSV Exception handler. */ void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief SVC Handler. */ void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Allocate a Secure context for the calling task. * * @param[in] ulSecureStackSize The size of the stack to be allocated on the * secure side for the calling task. */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); /** * @brief Free the task's secure context. * * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. */ void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* __PORT_ASM_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_MVE #error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE. #endif /* configENABLE_MVE */ /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M85" #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACROCOMMON_H #define PORTMACROCOMMON_H #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_FPU #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. #endif /* configENABLE_FPU */ #ifndef configENABLE_MPU #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. #endif /* configENABLE_MPU */ #ifndef configENABLE_TRUSTZONE #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ /** * @brief Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif #define portHAS_STACK_OVERFLOW_CHECKING 1 /*-----------------------------------------------------------*/ /** * @brief Extern declarations. */ extern BaseType_t xPortIsInsideInterrupt( void ); extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; #if ( configENABLE_TRUSTZONE == 1 ) extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_MPU == 1 ) extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief MPU specific constants. */ #if ( configENABLE_MPU == 1 ) #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #else #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* MPU regions. */ #define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_RAM_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ /* Device memory attributes used in MPU_MAIR registers. * * 8-bit values encoded as follows: * Bit[7:4] - 0000 - Device Memory * Bit[3:2] - 00 --> Device-nGnRnE * 01 --> Device-nGnRE * 10 --> Device-nGRE * 11 --> Device-GRE * Bit[1:0] - 00, Reserved. */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ /* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ /* Attributes used in MPU_RBAR registers. */ #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ /** * @brief Settings to define an MPU region. */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */ } MPURegionSettings_t; /** * @brief MPU settings as stored in the TCB. */ typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ } xMPU_SETTINGS; /*-----------------------------------------------------------*/ /** * @brief SVC numbers. */ #define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 /*-----------------------------------------------------------*/ /** * @brief Scheduler utilities. */ #define portYIELD() vPortYield() #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /** * @brief Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /** * @brief Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Allocate a secure context for the task. * * 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 context before it calls any secure function. * * @param[in] ulSecureStackSize The size of the secure stack to be allocated. */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) /** * @brief Called when a task is deleted to delete the task's secure context, * if it has one. * * @param[in] pxTCB The TCB of the task being deleted. */ #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. * * 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, * the privilege is not raised. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() #else #define portIS_PRIVILEGED() #define portRAISE_PRIVILEGE() #define portRESET_PRIVILEGE() #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief Barriers. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACROCOMMON_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CR5/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include #include /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS #error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. Refer to Cortex-A equivalent: http: /*www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */ #endif #ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET #error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. Refer to Cortex-A equivalent: http: /*www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */ #endif #ifndef configUNIQUE_INTERRUPT_PRIORITIES #error configUNIQUE_INTERRUPT_PRIORITIES must be defined. Refer to Cortex-A equivalent: http: /*www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */ #endif #ifndef configSETUP_TICK_INTERRUPT #error configSETUP_TICK_INTERRUPT() must be defined. Refer to Cortex-A equivalent: http: /*www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */ #endif /* configSETUP_TICK_INTERRUPT */ #ifndef configMAX_API_CALL_INTERRUPT_PRIORITY #error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. Refer to Cortex-A equivalent: http: /*www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */ #endif #if configMAX_API_CALL_INTERRUPT_PRIORITY == 0 #error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0 #endif #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 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #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. #endif #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /* In case security extensions are implemented. */ #if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) #error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) #endif /* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in * portmacro.h. */ #ifndef configCLEAR_TICK_INTERRUPT #define configCLEAR_TICK_INTERRUPT() #endif /* A critical section is exited when the critical section nesting count reaches * this value. */ #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 ) /* In all GICs 255 can be written to the priority mask register to unmask all * (but the lowest) interrupt priority. */ #define portUNMASK_VALUE ( 0xFFUL ) /* 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 * 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 * context. */ #define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 ) /* Constants required to setup the initial task context. */ #define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, IRQ enabled FIQ enabled. */ #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) #define portINTERRUPT_ENABLE_BIT ( 0x80UL ) #define portTHUMB_MODE_ADDRESS ( 0x01UL ) /* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary * point is zero. */ #define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 ) /* Masks all bits in the APSR other than the mode bits. */ #define portAPSR_MODE_BITS_MASK ( 0x1F ) /* The value of the mode bits in the APSR when the CPU is executing in user * mode. */ #define portAPSR_USER_MODE ( 0x10 ) /* The critical section macros only mask interrupts up to an application * determined priority level. Sometimes it is necessary to turn interrupt off in * the CPU itself before modifying certain hardware registers. */ #define portCPU_IRQ_DISABLE() \ __asm volatile ( "CPSID i" ::: "memory" ); \ __asm volatile ( "DSB" ); \ __asm volatile ( "ISB" ); #define portCPU_IRQ_ENABLE() \ __asm volatile ( "CPSIE i" ::: "memory" ); \ __asm volatile ( "DSB" ); \ __asm volatile ( "ISB" ); /* Macro to unmask all interrupt priorities. */ #define portCLEAR_INTERRUPT_MASK() \ { \ portCPU_IRQ_DISABLE(); \ portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \ __asm volatile ( "DSB \n" \ "ISB \n"); \ portCPU_IRQ_ENABLE(); \ } #define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portBIT_0_SET ( ( uint8_t ) 0x01 ) /* Let the user override the pre-loading of the initial LR with the address of * prvTaskExitError() in case is messes up unwinding of the stack in the * debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /* * The space on the stack required to hold the FPU registers. * * The ARM Cortex R5 processor implements the VFPv3-D16 FPU * architecture. This includes only 16 double-precision registers, * instead of 32 as is in VFPv3. The register bank can be viewed * either as sixteen 64-bit double-word registers (D0-D15) or * thirty-two 32-bit single-word registers (S0-S31), in both cases * the size of the bank remains the same. The FPU has also a 32-bit * status register. */ #define portFPU_REGISTER_WORDS ( ( 16 * 2 ) + 1 ) /*-----------------------------------------------------------*/ /* * Starts the first task executing. This function is necessarily written in * assembly code so is implemented in portASM.s. */ extern void vPortRestoreTaskContext( void ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /* * If the application provides an implementation of vApplicationIRQHandler(), * then it will get called directly without saving the FPU registers on * interrupt entry, and this weak implementation of * vApplicationFPUSafeIRQHandler() is just provided to remove linkage errors - * it should never actually get called so its implementation contains a * call to configASSERT() that will always fail. * * If the application provides its own implementation of * vApplicationFPUSafeIRQHandler() then the implementation of * vApplicationIRQHandler() provided in portASM.S will save the FPU registers * before calling it. * * Therefore, if the application writer wants FPU registers to be saved on * interrupt entry their IRQ handler must be called * vApplicationFPUSafeIRQHandler(), and if the application writer does not want * FPU registers to be saved on interrupt entry their IRQ handler must be * called vApplicationIRQHandler(). */ void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__((weak) ); /*-----------------------------------------------------------*/ /* 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 * 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 * automatically be set to 0 when the first task is started. */ volatile uint32_t ulCriticalNesting = 9999UL; /* 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. */ uint32_t ulPortTaskHasFPUContext = pdFALSE; /* Set to 1 to pend a context switch from an ISR. */ uint32_t ulPortYieldRequired = pdFALSE; /* Counts the interrupt nesting depth. A context switch is only performed if * if the nesting depth is 0. */ uint32_t ulPortInterruptNesting = 0UL; /* Used in asm code. */ __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 ulICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS; __attribute__( ( used ) ) const uint32_t ulMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { /* Setup the initial stack of the task. The stack is set exactly as * expected by the portRESTORE_CONTEXT() macro. * * 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 * GDB does not try decoding a non-existent return address. */ *pxTopOfStack = ( StackType_t ) NULL; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) NULL; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) NULL; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portINITIAL_SPSR; if( ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) != 0x00UL ) { /* The task will start in THUMB mode. */ *pxTopOfStack |= portTHUMB_MODE_BIT; } pxTopOfStack--; /* Next the return address, which in this case is the start of the task. */ *pxTopOfStack = ( StackType_t ) pxCode; pxTopOfStack--; /* Next all the registers other than the stack pointer. */ *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* R14 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; /* The task will start with a critical nesting count of 0 as interrupts are * enabled. */ *pxTopOfStack = portNO_CRITICAL_NESTING; #if( configUSE_TASK_FPU_SUPPORT == 1 ) { /* The task will start without a floating point context. A task that uses the floating point hardware must call vPortTaskUsesFPU() before executing any floating point instructions. */ pxTopOfStack--; *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; } #elif( configUSE_TASK_FPU_SUPPORT == 2 ) { /* The task will start with a floating point context. Leave enough space for the registers - and ensure they are initialized to 0. */ pxTopOfStack -= portFPU_REGISTER_WORDS; memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) ); pxTopOfStack--; *pxTopOfStack = pdTRUE; ulPortTaskHasFPUContext = pdTRUE; } #else { #error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined. } #endif /* configUSE_TASK_FPU_SUPPORT */ return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). * * Artificially force an assert() to be triggered if configASSERT() is * defined, then stop here so application writers can catch the error. */ configASSERT( ulPortInterruptNesting == ~0UL ); portDISABLE_INTERRUPTS(); for( ; ; ) { } } /*-----------------------------------------------------------*/ void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) { ( void ) ulICCIAR; configASSERT( ( volatile void * ) NULL ); } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) { uint32_t ulAPSR, ulCycles = 8; /* 8 bits per byte. */ #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET ); volatile uint8_t ucMaxPriorityValue; /* Determine how many priority bits are implemented in the GIC. * * Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to * all possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* Shift to the least significant bits. */ while( ( ucMaxPriorityValue & portBIT_0_SET ) != portBIT_0_SET ) { ucMaxPriorityValue >>= ( uint8_t ) 0x01; /* If ulCycles reaches 0 then ucMaxPriorityValue must have been * read as 0, indicating a misconfiguration. */ ulCycles--; if( ulCycles == 0 ) { break; } } /* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read * value. */ configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY ); /* Restore the clobbered interrupt priority register to its original * value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* Only continue if the CPU is not in User mode. The CPU must be in a * Privileged mode for the scheduler to start. */ __asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR )::"memory" ); ulAPSR &= portAPSR_MODE_BITS_MASK; configASSERT( ulAPSR != portAPSR_USER_MODE ); if( ulAPSR != portAPSR_USER_MODE ) { /* Only continue if the binary point value is set to its lowest possible * setting. See the comments in vPortValidateInterruptPriority() below for * more information. */ configASSERT( ( 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 * not execute while the scheduler is being started. Interrupts are * automatically turned back on in the CPU when the first task starts * executing. */ portCPU_IRQ_DISABLE(); /* Start the timer that generates the tick ISR. */ configSETUP_TICK_INTERRUPT(); /* Start the first task executing. */ vPortRestoreTaskContext(); } } /* 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 * possible value. prvTaskExitError() is referenced to prevent a compiler * warning about it being defined but not referenced in the case that the user * defines their own exit address. */ ( void ) prvTaskExitError; return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { /* Mask interrupts up to the max syscall interrupt priority. */ ulPortSetInterruptMask(); /* Now interrupts are disabled ulCriticalNesting can be accessed * directly. Increment ulCriticalNesting to keep a count of how many times * portENTER_CRITICAL() has been called. */ ulCriticalNesting++; /* 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 * 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 * assert function also uses a critical section. */ if( ulCriticalNesting == 1 ) { configASSERT( ulPortInterruptNesting == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { if( ulCriticalNesting > portNO_CRITICAL_NESTING ) { /* Decrement the nesting count as the critical section is being * exited. */ ulCriticalNesting--; /* If the nesting level has reached zero then all interrupt * priorities must be re-enabled. */ if( ulCriticalNesting == portNO_CRITICAL_NESTING ) { /* Critical nesting has reached zero so all interrupt priorities * should be unmasked. */ portCLEAR_INTERRUPT_MASK(); } } } /*-----------------------------------------------------------*/ void FreeRTOS_Tick_Handler( void ) { /* Set interrupt mask before altering scheduler structures. The tick * 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 * necessary to turn off interrupts in the CPU itself while the ICCPMR is being * updated. */ portCPU_IRQ_DISABLE(); portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); __asm volatile ( "dsb \n" "isb \n"::: "memory" ); portCPU_IRQ_ENABLE(); /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { ulPortYieldRequired = pdTRUE; } /* Ensure all interrupt priorities are active again. */ portCLEAR_INTERRUPT_MASK(); configCLEAR_TICK_INTERRUPT(); } /*-----------------------------------------------------------*/ #if( configUSE_TASK_FPU_SUPPORT != 2 ) void vPortTaskUsesFPU( void ) { uint32_t ulInitialFPSCR = 0; /* 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). */ ulPortTaskHasFPUContext = pdTRUE; /* Initialise the floating point status register. */ __asm volatile ( "FMXR FPSCR, %0" ::"r" ( ulInitialFPSCR ) : "memory" ); } #endif /* configUSE_TASK_FPU_SUPPORT */ /*-----------------------------------------------------------*/ void vPortClearInterruptMask( uint32_t ulNewMaskValue ) { if( ulNewMaskValue == pdFALSE ) { portCLEAR_INTERRUPT_MASK(); } } /*-----------------------------------------------------------*/ uint32_t ulPortSetInterruptMask( void ) { uint32_t ulReturn; /* Interrupt in the CPU must be turned off while the ICCPMR is being * updated. */ portCPU_IRQ_DISABLE(); if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ) { /* Interrupts were already masked. */ ulReturn = pdTRUE; } else { ulReturn = pdFALSE; portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); __asm volatile ( "dsb \n" "isb \n"::: "memory" ); } portCPU_IRQ_ENABLE(); return ulReturn; } /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. */ configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); /* Priority grouping: The interrupt controller (GIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined * to be pre-emption priority bits. The following assertion will fail if * this is not the case (if some bits represent a sub-priority). * * The priority grouping is configured by the GIC's binary point register * (ICCBPR). Writing 0 to ICCBPR will ensure it is set to its lowest * possible value (which may be above 0). */ configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); } #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CR5/portASM.S ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ .text .arm .set SYS_MODE, 0x1f .set SVC_MODE, 0x13 .set IRQ_MODE, 0x12 /* Hardware registers. */ .extern ulICCIAR .extern ulICCEOIR .extern ulICCPMR /* Variables and functions. */ .extern ulMaxAPIPriorityMask .extern _freertos_vector_table .extern pxCurrentTCB .extern vTaskSwitchContext .extern vApplicationIRQHandler .extern ulPortInterruptNesting .extern ulPortTaskHasFPUContext .global FreeRTOS_IRQ_Handler .global FreeRTOS_SWI_Handler .global vPortRestoreTaskContext .macro portSAVE_CONTEXT /* Save the LR and SPSR onto the system mode stack before switching to system mode to save the remaining system mode registers. */ SRSDB sp!, #SYS_MODE CPS #SYS_MODE PUSH {R0-R12, R14} /* Push the critical nesting count. */ LDR R2, ulCriticalNestingConst LDR R1, [R2] PUSH {R1} /* Does the task have a floating point context that needs saving? If ulPortTaskHasFPUContext is 0 then no. */ LDR R2, ulPortTaskHasFPUContextConst LDR R3, [R2] CMP R3, #0 /* Save the floating point context, if any. */ FMRXNE R1, FPSCR VPUSHNE {D0-D15} /*VPUSHNE {D16-D31}*/ PUSHNE {R1} /* Save ulPortTaskHasFPUContext itself. */ PUSH {R3} /* Save the stack pointer in the TCB. */ LDR R0, pxCurrentTCBConst LDR R1, [R0] STR SP, [R1] .endm ; /**********************************************************************/ .macro portRESTORE_CONTEXT /* Set the SP to point to the stack of the task being restored. */ LDR R0, pxCurrentTCBConst LDR R1, [R0] LDR SP, [R1] /* Is there a floating point context to restore? If the restored ulPortTaskHasFPUContext is zero then no. */ LDR R0, ulPortTaskHasFPUContextConst POP {R1} STR R1, [R0] CMP R1, #0 /* Restore the floating point context, if any. */ POPNE {R0} /*VPOPNE {D16-D31}*/ VPOPNE {D0-D15} VMSRNE FPSCR, R0 /* Restore the critical section nesting depth. */ LDR R0, ulCriticalNestingConst POP {R1} STR R1, [R0] /* Ensure the priority mask is correct for the critical nesting depth. */ LDR R2, ulICCPMRConst LDR R2, [R2] CMP R1, #0 MOVEQ R4, #255 LDRNE R4, ulMaxAPIPriorityMaskConst LDRNE R4, [R4] STR R4, [R2] /* Restore all system mode registers other than the SP (which is already being used). */ POP {R0-R12, R14} /* Return to the task code, loading CPSR on the way. */ RFEIA sp! .endm /****************************************************************************** * SVC handler is used to start the scheduler. *****************************************************************************/ .align 4 .type FreeRTOS_SWI_Handler, %function FreeRTOS_SWI_Handler: /* Save the context of the current task and select a new task to run. */ portSAVE_CONTEXT LDR R0, vTaskSwitchContextConst BLX R0 portRESTORE_CONTEXT /****************************************************************************** * vPortRestoreTaskContext is used to start the scheduler. *****************************************************************************/ .type vPortRestoreTaskContext, %function vPortRestoreTaskContext: /* Switch to system mode. */ CPS #SYS_MODE portRESTORE_CONTEXT .align 4 .type FreeRTOS_IRQ_Handler, %function FreeRTOS_IRQ_Handler: /* Return to the interrupted instruction. */ SUB lr, lr, #4 /* Push the return address and SPSR. */ PUSH {lr} MRS lr, SPSR PUSH {lr} /* Change to supervisor mode to allow reentry. */ CPS #SVC_MODE /* Push used registers. */ PUSH {r0-r4, r12} /* Increment nesting count. r3 holds the address of ulPortInterruptNesting for future use. r1 holds the original ulPortInterruptNesting value for future use. */ LDR r3, ulPortInterruptNestingConst LDR r1, [r3] ADD r4, r1, #1 STR r4, [r3] /* Read value from the interrupt acknowledge register, which is stored in r0 for future parameter and interrupt clearing use. */ LDR r2, ulICCIARConst LDR r2, [r2] LDR r0, [r2] /* Ensure bit 2 of the stack pointer is clear. r2 holds the bit 2 value for future use. _RB_ Is this ever needed provided the start of the stack is alligned on an 8-byte boundary? */ MOV r2, sp AND r2, r2, #4 SUB sp, sp, r2 /* Call the interrupt handler. */ PUSH {r0-r4, lr} LDR r1, vApplicationIRQHandlerConst BLX r1 POP {r0-r4, lr} ADD sp, sp, r2 CPSID i DSB ISB /* Write the value read from ICCIAR to ICCEOIR. */ LDR r4, ulICCEOIRConst LDR r4, [r4] STR r0, [r4] /* Restore the old nesting count. */ STR r1, [r3] /* A context switch is never performed if the nesting count is not 0. */ CMP r1, #0 BNE exit_without_switch /* Did the interrupt request a context switch? r1 holds the address of ulPortYieldRequired and r0 the value of ulPortYieldRequired for future use. */ LDR r1, =ulPortYieldRequired LDR r0, [r1] CMP r0, #0 BNE switch_before_exit exit_without_switch: /* No context switch. Restore used registers, LR_irq and SPSR before returning. */ POP {r0-r4, r12} CPS #IRQ_MODE POP {LR} MSR SPSR_cxsf, LR POP {LR} MOVS PC, LR switch_before_exit: /* A context swtich is to be performed. Clear the context switch pending flag. */ MOV r0, #0 STR r0, [r1] /* Restore used registers, LR-irq and SPSR before saving the context to the task stack. */ POP {r0-r4, r12} CPS #IRQ_MODE POP {LR} MSR SPSR_cxsf, LR POP {LR} portSAVE_CONTEXT /* Call the function that selects the new task to execute. vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD instructions, or 8 byte aligned stack allocated data. LR does not need saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. */ LDR R0, vTaskSwitchContextConst BLX R0 /* Restore the context of, and branch to, the task selected to execute next. */ portRESTORE_CONTEXT /****************************************************************************** * If the application provides an implementation of vApplicationIRQHandler(), * then it will get called directly without saving the FPU registers on * interrupt entry, and this weak implementation of * vApplicationIRQHandler() will not get called. * * If the application provides its own implementation of * vApplicationFPUSafeIRQHandler() then this implementation of * vApplicationIRQHandler() will be called, save the FPU registers, and then * call vApplicationFPUSafeIRQHandler(). * * Therefore, if the application writer wants FPU registers to be saved on * interrupt entry their IRQ handler must be called * vApplicationFPUSafeIRQHandler(), and if the application writer does not want * FPU registers to be saved on interrupt entry their IRQ handler must be * called vApplicationIRQHandler(). *****************************************************************************/ .align 4 .weak vApplicationIRQHandler .type vApplicationIRQHandler, %function vApplicationIRQHandler: PUSH {LR} FMRX R1, FPSCR VPUSH {D0-D15} PUSH {R1} LDR r1, vApplicationFPUSafeIRQHandlerConst BLX r1 POP {R0} VPOP {D0-D15} VMSR FPSCR, R0 POP {PC} ulICCIARConst: .word ulICCIAR ulICCEOIRConst: .word ulICCEOIR ulICCPMRConst: .word ulICCPMR pxCurrentTCBConst: .word pxCurrentTCB ulCriticalNestingConst: .word ulCriticalNesting ulPortTaskHasFPUContextConst: .word ulPortTaskHasFPUContext ulMaxAPIPriorityMaskConst: .word ulMaxAPIPriorityMask vTaskSwitchContextConst: .word vTaskSwitchContext vApplicationIRQHandlerConst: .word vApplicationIRQHandler ulPortInterruptNestingConst: .word ulPortInterruptNesting vApplicationFPUSafeIRQHandlerConst: .word vApplicationFPUSafeIRQHandler .end ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CR5/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /*-----------------------------------------------------------*/ /* Hardware specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Task utilities. */ /* Called at the end of an ISR that can cause a context switch. */ #define portEND_SWITCHING_ISR( xSwitchRequired ) \ { \ extern uint32_t ulPortYieldRequired; \ \ if( xSwitchRequired != pdFALSE ) \ { \ ulPortYieldRequired = pdTRUE; \ } \ } #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD() __asm volatile ( "SWI 0" ::: "memory" ); /*----------------------------------------------------------- * Critical section control *----------------------------------------------------------*/ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); extern uint32_t ulPortSetInterruptMask( void ); extern void vPortClearInterruptMask( uint32_t ulNewMaskValue ); extern void vPortInstallFreeRTOSVectorTable( void ); /* These macros do not globally disable/enable interrupts. They do mask off * interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */ #define portENTER_CRITICAL() vPortEnterCritical(); #define portEXIT_CRITICAL() vPortExitCritical(); #define portDISABLE_INTERRUPTS() ulPortSetInterruptMask() #define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 ) #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x ) /*-----------------------------------------------------------*/ /* 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 * macros is used. */ #define portTASK_FUNCTION_PROTO( 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 * handler for whichever peripheral is used to generate the RTOS tick. */ void FreeRTOS_Tick_Handler( void ); /* 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 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 by default. */ #if( configUSE_TASK_FPU_SUPPORT != 2 ) void vPortTaskUsesFPU( void ); #else /* Each task has an FPU context already, so define this function away to nothing to prevent it being called accidentally. */ #define vPortTaskUsesFPU() #endif /* configUSE_TASK_FPU_SUPPORT */ #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() #define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) #define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL ) /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* configASSERT */ #define portNOP() __asm volatile ( "NOP" ) #ifdef __cplusplus } /* extern C */ #endif /* The number of bits to shift for an interrupt priority is dependent on the * number of bits implemented by the interrupt controller. */ #if configUNIQUE_INTERRUPT_PRIORITIES == 16 #define portPRIORITY_SHIFT 4 #define portMAX_BINARY_POINT_VALUE 3 #elif configUNIQUE_INTERRUPT_PRIORITIES == 32 #define portPRIORITY_SHIFT 3 #define portMAX_BINARY_POINT_VALUE 2 #elif configUNIQUE_INTERRUPT_PRIORITIES == 64 #define portPRIORITY_SHIFT 2 #define portMAX_BINARY_POINT_VALUE 1 #elif configUNIQUE_INTERRUPT_PRIORITIES == 128 #define portPRIORITY_SHIFT 1 #define portMAX_BINARY_POINT_VALUE 0 #elif configUNIQUE_INTERRUPT_PRIORITIES == 256 #define portPRIORITY_SHIFT 0 #define portMAX_BINARY_POINT_VALUE 0 #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 #endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */ /* Interrupt controller access addresses. */ #define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 ) #define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C ) #define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 ) #define portICCBPR_BINARY_POINT_OFFSET ( 0x08 ) #define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 ) #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 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 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 portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) ) #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CRx_No_GIC/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #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. #endif #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #ifndef configSETUP_TICK_INTERRUPT #error configSETUP_TICK_INTERRUPT() must be defined in FreeRTOSConfig.h to call the function that sets up the tick interrupt. #endif #ifndef configCLEAR_TICK_INTERRUPT #error configCLEAR_TICK_INTERRUPT must be defined in FreeRTOSConfig.h to clear which ever interrupt was used to generate the tick interrupt. #endif /* A critical section is exited when the critical section nesting count reaches this value. */ #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 ) /* 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 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 context. */ #define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 ) /* Constants required to setup the initial task context. */ #define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, IRQ enabled FIQ enabled. */ #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) #define portTHUMB_MODE_ADDRESS ( 0x01UL ) /* Masks all bits in the APSR other than the mode bits. */ #define portAPSR_MODE_BITS_MASK ( 0x1F ) /* The value of the mode bits in the APSR when the CPU is executing in user mode. */ #define portAPSR_USER_MODE ( 0x10 ) /* 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /*-----------------------------------------------------------*/ /* * Starts the first task executing. This function is necessarily written in * assembly code so is implemented in portASM.s. */ extern void vPortRestoreTaskContext( void ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* 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 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 automatically be set to 0 when the first task is started. */ volatile uint32_t ulCriticalNesting = 9999UL; /* 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. */ volatile uint32_t ulPortTaskHasFPUContext = pdFALSE; /* Set to 1 to pend a context switch from an ISR. */ volatile uint32_t ulPortYieldRequired = pdFALSE; /* Counts the interrupt nesting depth. A context switch is only performed if if the nesting depth is 0. */ volatile uint32_t ulPortInterruptNesting = 0UL; /* Used in the asm file to clear an interrupt. */ __attribute__(( used )) const uint32_t ulICCEOIR = configEOI_ADDRESS; /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { /* Setup the initial stack of the task. The stack is set exactly as expected by the portRESTORE_CONTEXT() macro. 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 GDB does not try decoding a non-existent return address. */ *pxTopOfStack = ( StackType_t ) NULL; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) NULL; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) NULL; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portINITIAL_SPSR; if( ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) != 0x00UL ) { /* The task will start in THUMB mode. */ *pxTopOfStack |= portTHUMB_MODE_BIT; } pxTopOfStack--; /* Next the return address, which in this case is the start of the task. */ *pxTopOfStack = ( StackType_t ) pxCode; pxTopOfStack--; /* Next all the registers other than the stack pointer. */ *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* R14 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; /* The task will start with a critical nesting count of 0 as interrupts are enabled. */ *pxTopOfStack = portNO_CRITICAL_NESTING; pxTopOfStack--; /* The task will start without a floating point context. A task that uses the floating point hardware must call vPortTaskUsesFPU() before executing any floating point instructions. */ *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to its caller as there is nothing to return to. If a task wants to exit it should instead call vTaskDelete( NULL ). Artificially force an assert() to be triggered if configASSERT() is defined, then stop here so application writers can catch the error. */ configASSERT( ulPortInterruptNesting == ~0UL ); portDISABLE_INTERRUPTS(); for( ;; ); } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) { uint32_t ulAPSR; /* Only continue if the CPU is not in User mode. The CPU must be in a Privileged mode for the scheduler to start. */ __asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) :: "memory" ); ulAPSR &= portAPSR_MODE_BITS_MASK; configASSERT( ulAPSR != portAPSR_USER_MODE ); if( ulAPSR != portAPSR_USER_MODE ) { /* Start the timer that generates the tick ISR. */ portDISABLE_INTERRUPTS(); configSETUP_TICK_INTERRUPT(); /* Start the first task executing. */ vPortRestoreTaskContext(); } /* 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 possible value. prvTaskExitError() is referenced to prevent a compiler warning about it being defined but not referenced in the case that the user defines their own exit address. */ ( void ) prvTaskExitError; return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); /* Now interrupts are disabled ulCriticalNesting can be accessed directly. Increment ulCriticalNesting to keep a count of how many times portENTER_CRITICAL() has been called. */ ulCriticalNesting++; /* 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 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 assert function also uses a critical section. */ if( ulCriticalNesting == 1 ) { configASSERT( ulPortInterruptNesting == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { if( ulCriticalNesting > portNO_CRITICAL_NESTING ) { /* Decrement the nesting count as the critical section is being exited. */ ulCriticalNesting--; /* If the nesting level has reached zero then all interrupt priorities must be re-enabled. */ if( ulCriticalNesting == portNO_CRITICAL_NESTING ) { /* Critical nesting has reached zero so all interrupt priorities should be unmasked. */ portENABLE_INTERRUPTS(); } } } /*-----------------------------------------------------------*/ void FreeRTOS_Tick_Handler( void ) { uint32_t ulInterruptStatus; ulInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { ulPortYieldRequired = pdTRUE; } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulInterruptStatus ); configCLEAR_TICK_INTERRUPT(); } /*-----------------------------------------------------------*/ void vPortTaskUsesFPU( void ) { uint32_t ulInitialFPSCR = 0; /* 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). */ ulPortTaskHasFPUContext = pdTRUE; /* Initialise the floating point status register. */ __asm volatile ( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) : "memory" ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CRx_No_GIC/portASM.S ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ .text .arm .set SYS_MODE, 0x1f .set SVC_MODE, 0x13 .set IRQ_MODE, 0x12 /* Variables and functions. */ .extern ulMaxAPIPriorityMask .extern _freertos_vector_table .extern pxCurrentTCB .extern vTaskSwitchContext .extern vApplicationIRQHandler .extern ulPortInterruptNesting .extern ulPortTaskHasFPUContext .extern ulICCEOIR .extern ulPortYieldRequired .global FreeRTOS_IRQ_Handler .global FreeRTOS_SVC_Handler .global vPortRestoreTaskContext .macro portSAVE_CONTEXT /* Save the LR and SPSR onto the system mode stack before switching to system mode to save the remaining system mode registers. */ SRSDB sp!, #SYS_MODE CPS #SYS_MODE PUSH {R0-R12, R14} /* Push the critical nesting count. */ LDR R2, ulCriticalNestingConst LDR R1, [R2] PUSH {R1} /* Does the task have a floating point context that needs saving? If ulPortTaskHasFPUContext is 0 then no. */ LDR R2, ulPortTaskHasFPUContextConst LDR R3, [R2] CMP R3, #0 /* Save the floating point context, if any. */ FMRXNE R1, FPSCR VPUSHNE {D0-D15} #if configFPU_D32 == 1 VPUSHNE {D16-D31} #endif /* configFPU_D32 */ PUSHNE {R1} /* Save ulPortTaskHasFPUContext itself. */ PUSH {R3} /* Save the stack pointer in the TCB. */ LDR R0, pxCurrentTCBConst LDR R1, [R0] STR SP, [R1] .endm ; /**********************************************************************/ .macro portRESTORE_CONTEXT /* Set the SP to point to the stack of the task being restored. */ LDR R0, pxCurrentTCBConst LDR R1, [R0] LDR SP, [R1] /* Is there a floating point context to restore? If the restored ulPortTaskHasFPUContext is zero then no. */ LDR R0, ulPortTaskHasFPUContextConst POP {R1} STR R1, [R0] CMP R1, #0 /* Restore the floating point context, if any. */ POPNE {R0} #if configFPU_D32 == 1 VPOPNE {D16-D31} #endif /* configFPU_D32 */ VPOPNE {D0-D15} VMSRNE FPSCR, R0 /* Restore the critical section nesting depth. */ LDR R0, ulCriticalNestingConst POP {R1} STR R1, [R0] /* Restore all system mode registers other than the SP (which is already being used). */ POP {R0-R12, R14} /* Return to the task code, loading CPSR on the way. */ RFEIA sp! .endm /****************************************************************************** * SVC handler is used to yield. *****************************************************************************/ .align 4 .type FreeRTOS_SVC_Handler, %function FreeRTOS_SVC_Handler: /* Save the context of the current task and select a new task to run. */ portSAVE_CONTEXT LDR R0, vTaskSwitchContextConst BLX R0 portRESTORE_CONTEXT /****************************************************************************** * vPortRestoreTaskContext is used to start the scheduler. *****************************************************************************/ .align 4 .type vPortRestoreTaskContext, %function vPortRestoreTaskContext: /* Switch to system mode. */ CPS #SYS_MODE portRESTORE_CONTEXT .align 4 .type FreeRTOS_IRQ_Handler, %function FreeRTOS_IRQ_Handler: /* Return to the interrupted instruction. */ SUB lr, lr, #4 /* Push the return address and SPSR. */ PUSH {lr} MRS lr, SPSR PUSH {lr} /* Change to supervisor mode to allow reentry. */ CPS #0x13 /* Push used registers. */ PUSH {r0-r3, r12} /* Increment nesting count. r3 holds the address of ulPortInterruptNesting for future use. r1 holds the original ulPortInterruptNesting value for future use. */ LDR r3, ulPortInterruptNestingConst LDR r1, [r3] ADD r0, r1, #1 STR r0, [r3] /* Ensure bit 2 of the stack pointer is clear. r2 holds the bit 2 value for future use. */ MOV r0, sp AND r2, r0, #4 SUB sp, sp, r2 /* Call the interrupt handler. */ PUSH {r0-r3, lr} LDR r1, vApplicationIRQHandlerConst BLX r1 POP {r0-r3, lr} ADD sp, sp, r2 CPSID i DSB ISB /* Write to the EOI register. */ LDR r0, ulICCEOIRConst LDR r2, [r0] STR r0, [r2] /* Restore the old nesting count. */ STR r1, [r3] /* A context switch is never performed if the nesting count is not 0. */ CMP r1, #0 BNE exit_without_switch /* Did the interrupt request a context switch? r1 holds the address of ulPortYieldRequired and r0 the value of ulPortYieldRequired for future use. */ LDR r1, ulPortYieldRequiredConst LDR r0, [r1] CMP r0, #0 BNE switch_before_exit exit_without_switch: /* No context switch. Restore used registers, LR_irq and SPSR before returning. */ POP {r0-r3, r12} CPS #IRQ_MODE POP {LR} MSR SPSR_cxsf, LR POP {LR} MOVS PC, LR switch_before_exit: /* A context swtich is to be performed. Clear the context switch pending flag. */ MOV r0, #0 STR r0, [r1] /* Restore used registers, LR-irq and SPSR before saving the context to the task stack. */ POP {r0-r3, r12} CPS #IRQ_MODE POP {LR} MSR SPSR_cxsf, LR POP {LR} portSAVE_CONTEXT /* Call the function that selects the new task to execute. vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD instructions, or 8 byte aligned stack allocated data. LR does not need saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. */ LDR R0, vTaskSwitchContextConst BLX R0 /* Restore the context of, and branch to, the task selected to execute next. */ portRESTORE_CONTEXT ulICCEOIRConst: .word ulICCEOIR pxCurrentTCBConst: .word pxCurrentTCB ulCriticalNestingConst: .word ulCriticalNesting ulPortTaskHasFPUContextConst: .word ulPortTaskHasFPUContext vTaskSwitchContextConst: .word vTaskSwitchContext vApplicationIRQHandlerConst: .word vApplicationIRQHandler ulPortInterruptNestingConst: .word ulPortInterruptNesting ulPortYieldRequiredConst: .word ulPortYieldRequired .end ================================================ FILE: FreeRTOS-comparison/portable/GCC/ARM_CRx_No_GIC/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 /*-----------------------------------------------------------*/ /* Hardware specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Task utilities. */ /* Called at the end of an ISR that can cause a context switch. */ #define portEND_SWITCHING_ISR( xSwitchRequired )\ { \ extern volatile uint32_t ulPortYieldRequired; \ \ if( xSwitchRequired != pdFALSE ) \ { \ ulPortYieldRequired = pdTRUE; \ } \ } #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD() __asm volatile ( "SWI 0 \n" \ "ISB " ::: "memory" ); /*----------------------------------------------------------- * Critical section control *----------------------------------------------------------*/ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); extern uint32_t ulPortSetInterruptMask( void ); extern void vPortClearInterruptMask( uint32_t ulNewMaskValue ); extern void vPortInstallFreeRTOSVectorTable( void ); /* The I bit within the CPSR. */ #define portINTERRUPT_ENABLE_BIT ( 1 << 7 ) /* In the absence of a priority mask register, these functions and macros globally enable and disable interrupts. */ #define portENTER_CRITICAL() vPortEnterCritical(); #define portEXIT_CRITICAL() vPortExitCritical(); #define portENABLE_INTERRUPTS() __asm volatile ( "CPSIE i \n" ::: "memory" ); #define portDISABLE_INTERRUPTS() __asm volatile ( "CPSID i \n" \ "DSB \n" \ "ISB " ::: "memory" ); __attribute__( ( always_inline ) ) static __inline uint32_t portINLINE_SET_INTERRUPT_MASK_FROM_ISR( void ) { volatile uint32_t ulCPSR; __asm volatile ( "MRS %0, CPSR" : "=r" (ulCPSR) :: "memory" ); ulCPSR &= portINTERRUPT_ENABLE_BIT; portDISABLE_INTERRUPTS(); return ulCPSR; } #define portSET_INTERRUPT_MASK_FROM_ISR() portINLINE_SET_INTERRUPT_MASK_FROM_ISR() #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) do { if( x == 0 ) portENABLE_INTERRUPTS(); } while( 0 ) /*-----------------------------------------------------------*/ /* 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 macros is used. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) /* Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /* Prototype of the FreeRTOS tick handler. This must be installed as the handler for whichever peripheral is used to generate the RTOS tick. */ void FreeRTOS_Tick_Handler( void ); /* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() before any floating point instructions are executed. */ void vPortTaskUsesFPU( void ); #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() #define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) #define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL ) /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #define portNOP() __asm volatile( "NOP" ) #define portINLINE __inline #define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) #ifdef __cplusplus } /* extern C */ #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CA5_No_GIC/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* IAR includes. */ #include /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #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. #endif #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #ifndef configSETUP_TICK_INTERRUPT #error configSETUP_TICK_INTERRUPT() must be defined in FreeRTOSConfig.h to call the function that sets up the tick interrupt. A default that uses the PIT is provided in the official demo application. #endif #ifndef configCLEAR_TICK_INTERRUPT #error configCLEAR_TICK_INTERRUPT must be defined in FreeRTOSConfig.h to clear which ever interrupt was used to generate the tick interrupt. A default that uses the PIT is provided in the official demo application. #endif /* A critical section is exited when the critical section nesting count reaches this value. */ #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 ) /* 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 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 context. */ #define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 ) /* Constants required to setup the initial task context. */ #define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */ #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) #define portTHUMB_MODE_ADDRESS ( 0x01UL ) /* Masks all bits in the APSR other than the mode bits. */ #define portAPSR_MODE_BITS_MASK ( 0x1F ) /* The value of the mode bits in the APSR when the CPU is executing in user mode. */ #define portAPSR_USER_MODE ( 0x10 ) /*-----------------------------------------------------------*/ /* * Starts the first task executing. This function is necessarily written in * assembly code so is implemented in portASM.s. */ extern void vPortRestoreTaskContext( void ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* 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 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 automatically be set to 0 when the first task is started. */ volatile uint32_t ulCriticalNesting = 9999UL; /* 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. */ uint32_t ulPortTaskHasFPUContext = pdFALSE; /* Set to 1 to pend a context switch from an ISR. */ uint32_t ulPortYieldRequired = pdFALSE; /* Counts the interrupt nesting depth. A context switch is only performed if if the nesting depth is 0. */ uint32_t ulPortInterruptNesting = 0UL; /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { /* Setup the initial stack of the task. The stack is set exactly as expected by the portRESTORE_CONTEXT() macro. 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 GDB does not try decoding a non-existent return address. */ *pxTopOfStack = NULL; pxTopOfStack--; *pxTopOfStack = NULL; pxTopOfStack--; *pxTopOfStack = NULL; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portINITIAL_SPSR; if( ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) != 0x00UL ) { /* The task will start in THUMB mode. */ *pxTopOfStack |= portTHUMB_MODE_BIT; } pxTopOfStack--; /* Next the return address, which in this case is the start of the task. */ *pxTopOfStack = ( StackType_t ) pxCode; pxTopOfStack--; /* Next all the registers other than the stack pointer. */ *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* R14 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; /* The task will start with a critical nesting count of 0 as interrupts are enabled. */ *pxTopOfStack = portNO_CRITICAL_NESTING; pxTopOfStack--; /* The task will start without a floating point context. A task that uses the floating point hardware must call vPortTaskUsesFPU() before executing any floating point instructions. */ *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to its caller as there is nothing to return to. If a task wants to exit it should instead call vTaskDelete( NULL ). Artificially force an assert() to be triggered if configASSERT() is defined, then stop here so application writers can catch the error. */ configASSERT( ulPortInterruptNesting == ~0UL ); portDISABLE_INTERRUPTS(); for( ;; ); } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) { uint32_t ulAPSR; /* Only continue if the CPU is not in User mode. The CPU must be in a Privileged mode for the scheduler to start. */ __asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) ); ulAPSR &= portAPSR_MODE_BITS_MASK; configASSERT( ulAPSR != portAPSR_USER_MODE ); if( ulAPSR != portAPSR_USER_MODE ) { /* Start the timer that generates the tick ISR. */ configSETUP_TICK_INTERRUPT(); vPortRestoreTaskContext(); } /* 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 possible value. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); /* Now interrupts are disabled ulCriticalNesting can be accessed directly. Increment ulCriticalNesting to keep a count of how many times portENTER_CRITICAL() has been called. */ ulCriticalNesting++; /* 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 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 assert function also uses a critical section. */ if( ulCriticalNesting == 1 ) { configASSERT( ulPortInterruptNesting == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { if( ulCriticalNesting > portNO_CRITICAL_NESTING ) { /* Decrement the nesting count as the critical section is being exited. */ ulCriticalNesting--; /* If the nesting level has reached zero then all interrupt priorities must be re-enabled. */ if( ulCriticalNesting == portNO_CRITICAL_NESTING ) { /* Critical nesting has reached zero so all interrupt priorities should be unmasked. */ portENABLE_INTERRUPTS(); } } } /*-----------------------------------------------------------*/ void FreeRTOS_Tick_Handler( void ) { portDISABLE_INTERRUPTS(); /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { ulPortYieldRequired = pdTRUE; } portENABLE_INTERRUPTS(); configCLEAR_TICK_INTERRUPT(); } /*-----------------------------------------------------------*/ void vPortTaskUsesFPU( void ) { uint32_t ulInitialFPSCR = 0; /* 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). */ ulPortTaskHasFPUContext = pdTRUE; /* Initialise the floating point status register. */ __asm( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CA5_No_GIC/portASM.h ================================================ ;/* ; * FreeRTOS Kernel V10.5.1 ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * this software and associated documentation files (the "Software"), to deal in ; * the Software without restriction, including without limitation the rights to ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * the Software, and to permit persons to whom the Software is furnished to do so, ; * subject to the following conditions: ; * ; * The above copyright notice and this permission notice shall be included in all ; * copies or substantial portions of the Software. ; * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * ; * https://www.FreeRTOS.org ; * https://github.com/FreeRTOS ; * ; */ EXTERN vTaskSwitchContext EXTERN ulCriticalNesting EXTERN pxCurrentTCB EXTERN ulPortTaskHasFPUContext EXTERN ulAsmAPIPriorityMask portSAVE_CONTEXT macro ; Save the LR and SPSR onto the system mode stack before switching to ; system mode to save the remaining system mode registers SRSDB sp!, #SYS_MODE CPS #SYS_MODE PUSH {R0-R12, R14} ; Push the critical nesting count LDR R2, =ulCriticalNesting LDR R1, [R2] PUSH {R1} ; Does the task have a floating point context that needs saving? If ; ulPortTaskHasFPUContext is 0 then no. LDR R2, =ulPortTaskHasFPUContext LDR R3, [R2] CMP R3, #0 ; Save the floating point context, if any FMRXNE R1, FPSCR VPUSHNE {D0-D15} #if configFPU_D32 == 1 VPUSHNE {D16-D31} #endif ; configFPU_D32 PUSHNE {R1} ; Save ulPortTaskHasFPUContext itself PUSH {R3} ; Save the stack pointer in the TCB LDR R0, =pxCurrentTCB LDR R1, [R0] STR SP, [R1] endm ; /**********************************************************************/ portRESTORE_CONTEXT macro ; Set the SP to point to the stack of the task being restored. LDR R0, =pxCurrentTCB LDR R1, [R0] LDR SP, [R1] ; Is there a floating point context to restore? If the restored ; ulPortTaskHasFPUContext is zero then no. LDR R0, =ulPortTaskHasFPUContext POP {R1} STR R1, [R0] CMP R1, #0 ; Restore the floating point context, if any POPNE {R0} #if configFPU_D32 == 1 VPOPNE {D16-D31} #endif ; configFPU_D32 VPOPNE {D0-D15} VMSRNE FPSCR, R0 ; Restore the critical section nesting depth LDR R0, =ulCriticalNesting POP {R1} STR R1, [R0] ; Restore all system mode registers other than the SP (which is already ; being used) POP {R0-R12, R14} ; Return to the task code, loading CPSR on the way. CPSR has the interrupt ; enable bit set appropriately for the task about to execute. RFEIA sp! endm ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CA5_No_GIC/portASM.s ================================================ ;/* ; * FreeRTOS Kernel V10.5.1 ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * this software and associated documentation files (the "Software"), to deal in ; * the Software without restriction, including without limitation the rights to ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * the Software, and to permit persons to whom the Software is furnished to do so, ; * subject to the following conditions: ; * ; * The above copyright notice and this permission notice shall be included in all ; * copies or substantial portions of the Software. ; * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * ; * https://www.FreeRTOS.org ; * https://github.com/FreeRTOS ; * ; */ INCLUDE FreeRTOSConfig.h INCLUDE portmacro.h EXTERN vTaskSwitchContext EXTERN ulPortYieldRequired EXTERN ulPortInterruptNesting EXTERN vApplicationIRQHandler PUBLIC FreeRTOS_SWI_Handler PUBLIC FreeRTOS_IRQ_Handler PUBLIC vPortRestoreTaskContext SYS_MODE EQU 0x1f SVC_MODE EQU 0x13 IRQ_MODE EQU 0x12 SECTION .text:CODE:ROOT(2) ARM INCLUDE portASM.h ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SVC handler is used to yield a task. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; FreeRTOS_SWI_Handler PRESERVE8 ; Save the context of the current task and select a new task to run. portSAVE_CONTEXT LDR R0, =vTaskSwitchContext BLX R0 portRESTORE_CONTEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; vPortRestoreTaskContext is used to start the scheduler. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; vPortRestoreTaskContext PRESERVE8 ; Switch to system mode CPS #SYS_MODE portRESTORE_CONTEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; IRQ interrupt handler used when individual priorities cannot be masked ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; FreeRTOS_IRQ_Handler PRESERVE8 ; Return to the interrupted instruction. SUB lr, lr, #4 ; Push the return address and SPSR PUSH {lr} MRS lr, SPSR PUSH {lr} ; Change to supervisor mode to allow reentry. CPS #SVC_MODE ; Push used registers. PUSH {r0-r4, r12} ; Increment nesting count. r3 holds the address of ulPortInterruptNesting ; for future use. r1 holds the original ulPortInterruptNesting value for ; future use. LDR r3, =ulPortInterruptNesting LDR r1, [r3] ADD r4, r1, #1 STR r4, [r3] ; Ensure bit 2 of the stack pointer is clear. r2 holds the bit 2 value for ; future use. MOV r2, sp AND r2, r2, #4 SUB sp, sp, r2 PUSH {r0-r4, lr} ; Call the port part specific handler. LDR r0, =vApplicationIRQHandler BLX r0 POP {r0-r4, lr} ADD sp, sp, r2 CPSID i ; Write to the EOI register. LDR r4, =configEOI_ADDRESS STR r0, [r4] ; Restore the old nesting count STR r1, [r3] ; A context switch is never performed if the nesting count is not 0. CMP r1, #0 BNE exit_without_switch ; Did the interrupt request a context switch? r1 holds the address of ; ulPortYieldRequired and r0 the value of ulPortYieldRequired for future ; use. LDR r1, =ulPortYieldRequired LDR r0, [r1] CMP r0, #0 BNE switch_before_exit exit_without_switch ; No context switch. Restore used registers, LR_irq and SPSR before ; returning. POP {r0-r4, r12} CPS #IRQ_MODE POP {LR} MSR SPSR_cxsf, LR POP {LR} MOVS PC, LR switch_before_exit ; A context switch is to be performed. Clear the context switch pending ; flag. MOV r0, #0 STR r0, [r1] ; Restore used registers, LR-irq and SPSR before saving the context ; to the task stack. POP {r0-r4, r12} CPS #IRQ_MODE POP {LR} MSR SPSR_cxsf, LR POP {LR} portSAVE_CONTEXT ; Call the function that selects the new task to execute. ; vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD ; instructions, or 8 byte aligned stack allocated data. LR does not need ; saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. LDR r0, =vTaskSwitchContext BLX r0 ; Restore the context of, and branch to, the task selected to execute next. portRESTORE_CONTEXT END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CA5_No_GIC/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H /* IAR includes. */ #ifdef __ICCARM__ #include #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 /*-----------------------------------------------------------*/ /* Hardware specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Task utilities. */ /* Called at the end of an ISR that can cause a context switch. */ #define portEND_SWITCHING_ISR( xSwitchRequired )\ { \ extern uint32_t ulPortYieldRequired; \ \ if( xSwitchRequired != pdFALSE ) \ { \ ulPortYieldRequired = pdTRUE; \ } \ } #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD() __asm volatile ( "SWI 0" ); __ISB() /*----------------------------------------------------------- * Critical section control *----------------------------------------------------------*/ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); extern uint32_t ulPortSetInterruptMask( void ); extern void vPortClearInterruptMask( uint32_t ulNewMaskValue ); #define portENTER_CRITICAL() vPortEnterCritical(); #define portEXIT_CRITICAL() vPortExitCritical(); #define portDISABLE_INTERRUPTS() __disable_irq(); __DSB(); __ISB() /* No priority mask register so global disable is used. */ #define portENABLE_INTERRUPTS() __enable_irq() #define portSET_INTERRUPT_MASK_FROM_ISR() __get_interrupt_state(); __disable_irq() /* No priority mask register so global disable is used. */ #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) __set_interrupt_state(x) /*-----------------------------------------------------------*/ /* 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 macros is used. */ #define portTASK_FUNCTION_PROTO( 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 handler for whichever peripheral is used to generate the RTOS tick. */ void FreeRTOS_Tick_Handler( void ); /* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() before any floating point instructions are executed. */ void vPortTaskUsesFPU( void ); #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #define portNOP() __asm volatile( "NOP" ) #ifdef __cplusplus } /* extern C */ #endif /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in the source code because to do so would cause other compilers to generate warnings. */ #pragma diag_suppress=Pe191 #pragma diag_suppress=Pa082 #endif /* __ICCARM__ */ #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CA9/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* IAR includes. */ #include /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #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 #endif #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 #endif #ifndef configUNIQUE_INTERRUPT_PRIORITIES #error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif #ifndef configSETUP_TICK_INTERRUPT #error configSETUP_TICK_INTERRUPT() must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif /* configSETUP_TICK_INTERRUPT */ #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 #endif #if configMAX_API_CALL_INTERRUPT_PRIORITY == 0 #error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0 #endif #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 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #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. #endif #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /* In case security extensions are implemented. */ #if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) #error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) #endif #ifndef configCLEAR_TICK_INTERRUPT #define configCLEAR_TICK_INTERRUPT() #endif /* A critical section is exited when the critical section nesting count reaches this value. */ #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 ) /* In all GICs 255 can be written to the priority mask register to unmask all (but the lowest) interrupt priority. */ #define portUNMASK_VALUE ( 0xFFUL ) /* 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 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 context. */ #define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 ) /* Constants required to setup the initial task context. */ #define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */ #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) #define portTHUMB_MODE_ADDRESS ( 0x01UL ) /* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary point is zero. */ #define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 ) /* Masks all bits in the APSR other than the mode bits. */ #define portAPSR_MODE_BITS_MASK ( 0x1F ) /* The value of the mode bits in the APSR when the CPU is executing in user mode. */ #define portAPSR_USER_MODE ( 0x10 ) /* Macro to unmask all interrupt priorities. */ #define portCLEAR_INTERRUPT_MASK() \ { \ __disable_irq(); \ portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \ __asm( "DSB \n" \ "ISB \n" ); \ __enable_irq(); \ } /*-----------------------------------------------------------*/ /* * Starts the first task executing. This function is necessarily written in * assembly code so is implemented in portASM.s. */ extern void vPortRestoreTaskContext( void ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* 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 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 automatically be set to 0 when the first task is started. */ volatile uint32_t ulCriticalNesting = 9999UL; /* 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. */ uint32_t ulPortTaskHasFPUContext = pdFALSE; /* Set to 1 to pend a context switch from an ISR. */ uint32_t ulPortYieldRequired = pdFALSE; /* Counts the interrupt nesting depth. A context switch is only performed if if the nesting depth is 0. */ uint32_t ulPortInterruptNesting = 0UL; /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { /* Setup the initial stack of the task. The stack is set exactly as expected by the portRESTORE_CONTEXT() macro. 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 GDB does not try decoding a non-existent return address. */ *pxTopOfStack = NULL; pxTopOfStack--; *pxTopOfStack = NULL; pxTopOfStack--; *pxTopOfStack = NULL; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portINITIAL_SPSR; if( ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) != 0x00UL ) { /* The task will start in THUMB mode. */ *pxTopOfStack |= portTHUMB_MODE_BIT; } pxTopOfStack--; /* Next the return address, which in this case is the start of the task. */ *pxTopOfStack = ( StackType_t ) pxCode; pxTopOfStack--; /* Next all the registers other than the stack pointer. */ *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* R14 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; /* The task will start with a critical nesting count of 0 as interrupts are enabled. */ *pxTopOfStack = portNO_CRITICAL_NESTING; pxTopOfStack--; /* The task will start without a floating point context. A task that uses the floating point hardware must call vPortTaskUsesFPU() before executing any floating point instructions. */ *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to its caller as there is nothing to return to. If a task wants to exit it should instead call vTaskDelete( NULL ). Artificially force an assert() to be triggered if configASSERT() is defined, then stop here so application writers can catch the error. */ configASSERT( ulPortInterruptNesting == ~0UL ); portDISABLE_INTERRUPTS(); for( ;; ); } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) { uint32_t ulAPSR; /* Only continue if the CPU is not in User mode. The CPU must be in a Privileged mode for the scheduler to start. */ __asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) ); ulAPSR &= portAPSR_MODE_BITS_MASK; configASSERT( ulAPSR != portAPSR_USER_MODE ); if( ulAPSR != portAPSR_USER_MODE ) { /* Only continue if the binary point value is set to its lowest possible setting. See the comments in vPortValidateInterruptPriority() below for more information. */ configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ) { /* Start the timer that generates the tick ISR. */ configSETUP_TICK_INTERRUPT(); __enable_irq(); vPortRestoreTaskContext(); } } /* 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 possible value. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { /* Disable interrupts as per portDISABLE_INTERRUPTS(); */ ulPortSetInterruptMask(); /* Now interrupts are disabled ulCriticalNesting can be accessed directly. Increment ulCriticalNesting to keep a count of how many times portENTER_CRITICAL() has been called. */ ulCriticalNesting++; /* 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 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 assert function also uses a critical section. */ if( ulCriticalNesting == 1 ) { configASSERT( ulPortInterruptNesting == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { if( ulCriticalNesting > portNO_CRITICAL_NESTING ) { /* Decrement the nesting count as the critical section is being exited. */ ulCriticalNesting--; /* If the nesting level has reached zero then all interrupt priorities must be re-enabled. */ if( ulCriticalNesting == portNO_CRITICAL_NESTING ) { /* Critical nesting has reached zero so all interrupt priorities should be unmasked. */ portCLEAR_INTERRUPT_MASK(); } } } /*-----------------------------------------------------------*/ void FreeRTOS_Tick_Handler( void ) { /* Set interrupt mask before altering scheduler structures. The tick 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. */ __disable_irq(); portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); __asm( "DSB \n" "ISB \n" ); __enable_irq(); /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { ulPortYieldRequired = pdTRUE; } /* Ensure all interrupt priorities are active again. */ portCLEAR_INTERRUPT_MASK(); configCLEAR_TICK_INTERRUPT(); } /*-----------------------------------------------------------*/ void vPortTaskUsesFPU( void ) { uint32_t ulInitialFPSCR = 0; /* 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). */ ulPortTaskHasFPUContext = pdTRUE; /* Initialise the floating point status register. */ __asm( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) ); } /*-----------------------------------------------------------*/ void vPortClearInterruptMask( uint32_t ulNewMaskValue ) { if( ulNewMaskValue == pdFALSE ) { portCLEAR_INTERRUPT_MASK(); } } /*-----------------------------------------------------------*/ uint32_t ulPortSetInterruptMask( void ) { uint32_t ulReturn; __disable_irq(); if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ) { /* Interrupts were already masked. */ ulReturn = pdTRUE; } else { ulReturn = pdFALSE; portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); __asm( "DSB \n" "ISB \n" ); } __enable_irq(); return ulReturn; } /*-----------------------------------------------------------*/ #if( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { /* The following assertion will fail if a service routine (ISR) for an interrupt that has been assigned a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API function. ISR safe FreeRTOS API functions must *only* be called from interrupts that have been assigned a priority at or below configMAX_SYSCALL_INTERRUPT_PRIORITY. Numerically low interrupt priority numbers represent logically high interrupt priorities, therefore the priority of the interrupt must be set to a value equal to or numerically *higher* than configMAX_SYSCALL_INTERRUPT_PRIORITY. FreeRTOS maintains separate thread and ISR API functions to ensure interrupt entry is as fast and simple as possible. The following links provide detailed information: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); /* Priority grouping: The interrupt controller (GIC) allows the bits that define each interrupt's priority to be split between bits that define the interrupt's pre-emption priority bits and bits that define the interrupt's sub-priority. For simplicity all bits must be defined to be pre-emption priority bits. The following assertion will fail if this is not the case (if some bits represent a sub-priority). 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 possible value (which may be above 0). */ configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); } #endif /* configASSERT_DEFINED */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CA9/portASM.h ================================================ ;/* ; * FreeRTOS Kernel V10.5.1 ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * this software and associated documentation files (the "Software"), to deal in ; * the Software without restriction, including without limitation the rights to ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * the Software, and to permit persons to whom the Software is furnished to do so, ; * subject to the following conditions: ; * ; * The above copyright notice and this permission notice shall be included in all ; * copies or substantial portions of the Software. ; * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * ; * https://www.FreeRTOS.org ; * https://github.com/FreeRTOS ; * ; */ EXTERN vTaskSwitchContext EXTERN ulCriticalNesting EXTERN pxCurrentTCB EXTERN ulPortTaskHasFPUContext EXTERN ulAsmAPIPriorityMask portSAVE_CONTEXT macro ; Save the LR and SPSR onto the system mode stack before switching to ; system mode to save the remaining system mode registers SRSDB sp!, #SYS_MODE CPS #SYS_MODE PUSH {R0-R12, R14} ; Push the critical nesting count LDR R2, =ulCriticalNesting LDR R1, [R2] PUSH {R1} ; Does the task have a floating point context that needs saving? If ; ulPortTaskHasFPUContext is 0 then no. LDR R2, =ulPortTaskHasFPUContext LDR R3, [R2] CMP R3, #0 ; Save the floating point context, if any FMRXNE R1, FPSCR VPUSHNE {D0-D15} VPUSHNE {D16-D31} PUSHNE {R1} ; Save ulPortTaskHasFPUContext itself PUSH {R3} ; Save the stack pointer in the TCB LDR R0, =pxCurrentTCB LDR R1, [R0] STR SP, [R1] endm ; /**********************************************************************/ portRESTORE_CONTEXT macro ; Set the SP to point to the stack of the task being restored. LDR R0, =pxCurrentTCB LDR R1, [R0] LDR SP, [R1] ; Is there a floating point context to restore? If the restored ; ulPortTaskHasFPUContext is zero then no. LDR R0, =ulPortTaskHasFPUContext POP {R1} STR R1, [R0] CMP R1, #0 ; Restore the floating point context, if any POPNE {R0} VPOPNE {D16-D31} VPOPNE {D0-D15} VMSRNE FPSCR, R0 ; Restore the critical section nesting depth LDR R0, =ulCriticalNesting POP {R1} STR R1, [R0] ; Ensure the priority mask is correct for the critical nesting depth LDR R2, =portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS CMP R1, #0 MOVEQ R4, #255 LDRNE R4, =( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) STR R4, [r2] ; Restore all system mode registers other than the SP (which is already ; being used) POP {R0-R12, R14} ; Return to the task code, loading CPSR on the way. RFEIA sp! endm ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CA9/portASM.s ================================================ ;/* ; * FreeRTOS Kernel V10.5.1 ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * this software and associated documentation files (the "Software"), to deal in ; * the Software without restriction, including without limitation the rights to ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * the Software, and to permit persons to whom the Software is furnished to do so, ; * subject to the following conditions: ; * ; * The above copyright notice and this permission notice shall be included in all ; * copies or substantial portions of the Software. ; * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * ; * https://www.FreeRTOS.org ; * https://github.com/FreeRTOS ; * ; */ INCLUDE FreeRTOSConfig.h INCLUDE portmacro.h EXTERN vApplicationIRQHandler EXTERN vTaskSwitchContext EXTERN ulPortYieldRequired EXTERN ulPortInterruptNesting PUBLIC FreeRTOS_SWI_Handler PUBLIC FreeRTOS_IRQ_Handler PUBLIC vPortRestoreTaskContext SYS_MODE EQU 0x1f SVC_MODE EQU 0x13 IRQ_MODE EQU 0x12 SECTION .text:CODE:ROOT(2) ARM INCLUDE portASM.h ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SVC handler is used to yield a task. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; FreeRTOS_SWI_Handler PRESERVE8 ; Save the context of the current task and select a new task to run. portSAVE_CONTEXT LDR R0, =vTaskSwitchContext BLX R0 portRESTORE_CONTEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; vPortRestoreTaskContext is used to start the scheduler. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; vPortRestoreTaskContext ; Switch to system mode CPS #SYS_MODE portRESTORE_CONTEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; PL390 GIC interrupt handler ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; FreeRTOS_IRQ_Handler ; Return to the interrupted instruction. SUB lr, lr, #4 ; Push the return address and SPSR PUSH {lr} MRS lr, SPSR PUSH {lr} ; Change to supervisor mode to allow reentry. CPS #SVC_MODE ; Push used registers. PUSH {r0-r4, r12} ; Increment nesting count. r3 holds the address of ulPortInterruptNesting ; for future use. r1 holds the original ulPortInterruptNesting value for ; future use. LDR r3, =ulPortInterruptNesting LDR r1, [r3] ADD r4, r1, #1 STR r4, [r3] ; Read value from the interrupt acknowledge register, which is stored in r0 ; for future parameter and interrupt clearing use. LDR r2, =portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS LDR r0, [r2] ; Ensure bit 2 of the stack pointer is clear. r2 holds the bit 2 value for ; future use. _RB_ Is this ever necessary if start of stack is 8-byte aligned? MOV r2, sp AND r2, r2, #4 SUB sp, sp, r2 ; Call the interrupt handler. r4 is pushed to maintain alignment. PUSH {r0-r4, lr} LDR r1, =vApplicationIRQHandler BLX r1 POP {r0-r4, lr} ADD sp, sp, r2 CPSID i ; Write the value read from ICCIAR to ICCEOIR LDR r4, =portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS STR r0, [r4] ; Restore the old nesting count STR r1, [r3] ; A context switch is never performed if the nesting count is not 0 CMP r1, #0 BNE exit_without_switch ; Did the interrupt request a context switch? r1 holds the address of ; ulPortYieldRequired and r0 the value of ulPortYieldRequired for future ; use. LDR r1, =ulPortYieldRequired LDR r0, [r1] CMP r0, #0 BNE switch_before_exit exit_without_switch ; No context switch. Restore used registers, LR_irq and SPSR before ; returning. POP {r0-r4, r12} CPS #IRQ_MODE POP {LR} MSR SPSR_cxsf, LR POP {LR} MOVS PC, LR switch_before_exit ; A context switch is to be performed. Clear the context switch pending ; flag. MOV r0, #0 STR r0, [r1] ; Restore used registers, LR-irq and SPSR before saving the context ; to the task stack. POP {r0-r4, r12} CPS #IRQ_MODE POP {LR} MSR SPSR_cxsf, LR POP {LR} portSAVE_CONTEXT ; Call the function that selects the new task to execute. ; vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD ; instructions, or 8 byte aligned stack allocated data. LR does not need ; saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. LDR r0, =vTaskSwitchContext BLX r0 ; Restore the context of, and branch to, the task selected to execute next. portRESTORE_CONTEXT END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CA9/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H /* IAR includes. */ #ifdef __ICCARM__ #include #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 /*-----------------------------------------------------------*/ /* Hardware specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Task utilities. */ /* Called at the end of an ISR that can cause a context switch. */ #define portEND_SWITCHING_ISR( xSwitchRequired )\ { \ extern uint32_t ulPortYieldRequired; \ \ if( xSwitchRequired != pdFALSE ) \ { \ ulPortYieldRequired = pdTRUE; \ } \ } #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD() __asm( "SWI 0" ); /*----------------------------------------------------------- * Critical section control *----------------------------------------------------------*/ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); extern uint32_t ulPortSetInterruptMask( void ); extern void vPortClearInterruptMask( uint32_t ulNewMaskValue ); /* These macros do not globally disable/enable interrupts. They do mask off interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */ #define portENTER_CRITICAL() vPortEnterCritical(); #define portEXIT_CRITICAL() vPortExitCritical(); #define portDISABLE_INTERRUPTS() ulPortSetInterruptMask() #define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 ) #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x) /*-----------------------------------------------------------*/ /* 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 macros is used. */ #define portTASK_FUNCTION_PROTO( 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 handler for whichever peripheral is used to generate the RTOS tick. */ void FreeRTOS_Tick_Handler( void ); /* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() before any floating point instructions are executed. */ void vPortTaskUsesFPU( void ); #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() #define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) #define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL ) /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* configASSERT */ #define portNOP() __asm volatile( "NOP" ) #ifdef __cplusplus } /* extern C */ #endif /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in the source code because to do so would cause other compilers to generate warnings. */ #pragma diag_suppress=Pe191 #pragma diag_suppress=Pa082 #endif /* __ICCARM__ */ /* The number of bits to shift for an interrupt priority is dependent on the number of bits implemented by the interrupt controller. */ #if configUNIQUE_INTERRUPT_PRIORITIES == 16 #define portPRIORITY_SHIFT 4 #define portMAX_BINARY_POINT_VALUE 3 #elif configUNIQUE_INTERRUPT_PRIORITIES == 32 #define portPRIORITY_SHIFT 3 #define portMAX_BINARY_POINT_VALUE 2 #elif configUNIQUE_INTERRUPT_PRIORITIES == 64 #define portPRIORITY_SHIFT 2 #define portMAX_BINARY_POINT_VALUE 1 #elif configUNIQUE_INTERRUPT_PRIORITIES == 128 #define portPRIORITY_SHIFT 1 #define portMAX_BINARY_POINT_VALUE 0 #elif configUNIQUE_INTERRUPT_PRIORITIES == 256 #define portPRIORITY_SHIFT 0 #define portMAX_BINARY_POINT_VALUE 0 #else #error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware #endif /* Interrupt controller access addresses. */ #define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 ) #define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C ) #define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 ) #define portICCBPR_BINARY_POINT_OFFSET ( 0x08 ) #define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 ) #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 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 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 portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) ) #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM0/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM0 port. *----------------------------------------------------------*/ /* IAR includes. */ #include "intrinsics.h" /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) /* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is * defined. The value 255 should also ensure backward compatibility. * FreeRTOS.org versions prior to V4.3.0 did not include this definition. */ #ifndef configKERNEL_INTERRUPT_PRIORITY #define configKERNEL_INTERRUPT_PRIORITY 0 #endif /* Each task maintains its own interrupt status in the critical nesting * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* The systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /* A fiddle factor to estimate the number of SysTick counts that would have * occurred while the SysTick counter is stopped during tickless idle * calculations. */ #ifndef portMISSED_COUNTS_FACTOR #define portMISSED_COUNTS_FACTOR ( 94UL ) #endif /* The number of SysTick increments that make up one tick period. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulTimerCountsForOneTick = 0; #endif /* configUSE_TICKLESS_IDLE */ /* The maximum number of tick periods that can be suppressed is limited by the * 24 bit resolution of the SysTick timer. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t xMaximumPossibleSuppressedTicks = 0; #endif /* configUSE_TICKLESS_IDLE */ /* Compensate for the CPU cycles that pass while the SysTick is stopped (low * power functionality only. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /* Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ); /* * Exception handlers. */ void xPortSysTickHandler( void ); /* * Start first task is a separate function so it can be tested in isolation. */ extern void vPortStartFirstTask( void ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 8; /* R11..R4. */ return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). * * Artificially force an assert() to be triggered if configASSERT() is * defined, then stop here so application writers can catch the error. */ configASSERT( uxCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); for( ; ; ) { } } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Start the first task. */ vPortStartFirstTask(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortYield( void ) { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET; /* Barriers are normally not required but do ensure the code is completely * within the specified behaviour for the architecture. */ __DSB(); __ISB(); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); uxCriticalNesting++; __DSB(); __ISB(); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ /* * Setup the systick timer to generate the tick interrupts at the required * frequency. */ __weak void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); } /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __weak void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __disable_interrupt(); __DSB(); __ISB(); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the __disable_interrupt() * call above. */ __enable_interrupt(); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __DSB(); __WFI(); __ISB(); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the __disable_interrupt() call above. */ __enable_interrupt(); __DSB(); __ISB(); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __disable_interrupt(); __DSB(); __ISB(); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __enable_interrupt(); } } #endif /* configUSE_TICKLESS_IDLE */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM0/portasm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #include RSEG CODE:CODE(2) thumb EXTERN vPortYieldFromISR EXTERN pxCurrentTCB EXTERN vTaskSwitchContext PUBLIC vSetMSP PUBLIC xPortPendSVHandler PUBLIC vPortSVCHandler PUBLIC vPortStartFirstTask PUBLIC ulSetInterruptMaskFromISR PUBLIC vClearInterruptMaskFromISR /*-----------------------------------------------------------*/ vSetMSP msr msp, r0 bx lr /*-----------------------------------------------------------*/ xPortPendSVHandler: mrs r0, psp ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */ ldr r2, [r3] subs r0, r0, #32 /* Make space for the remaining low registers. */ str r0, [r2] /* Save the new top of stack. */ stmia r0!, {r4-r7} /* Store the low registers that are not saved automatically. */ mov r4, r8 /* Store the high registers. */ mov r5, r9 mov r6, r10 mov r7, r11 stmia r0!, {r4-r7} push {r3, r14} cpsid i bl vTaskSwitchContext cpsie i pop {r2, r3} /* lr goes in r3. r2 now holds tcb pointer. */ ldr r1, [r2] ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */ adds r0, r0, #16 /* Move to the high registers. */ ldmia r0!, {r4-r7} /* Pop the high registers. */ mov r8, r4 mov r9, r5 mov r10, r6 mov r11, r7 msr psp, r0 /* Remember the new top of stack for the task. */ subs r0, r0, #32 /* Go back for the low registers that are not automatically restored. */ ldmia r0!, {r4-r7} /* Pop low registers. */ bx r3 /*-----------------------------------------------------------*/ vPortSVCHandler; /* This function is no longer used, but retained for backward compatibility. */ bx lr /*-----------------------------------------------------------*/ vPortStartFirstTask /* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector table offset register that can be used to locate the initial stack value. Not all M0 parts have the application vector table at address 0. */ ldr r3, =pxCurrentTCB /* Obtain location of pxCurrentTCB. */ ldr r1, [r3] ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ movs r0, #2 /* Switch to the psp stack. */ msr CONTROL, r0 isb pop {r0-r5} /* Pop the registers that are saved automatically. */ mov lr, r5 /* lr is now in r5. */ pop {r3} /* The return address is now in r3. */ pop {r2} /* Pop and discard the XPSR. */ cpsie i /* The first task has its context and interrupts can be enabled. */ bx r3 /* Jump to the user defined task code. */ /*-----------------------------------------------------------*/ ulSetInterruptMaskFromISR mrs r0, PRIMASK cpsid i bx lr /*-----------------------------------------------------------*/ vClearInterruptMaskFromISR msr PRIMASK, r0 bx lr END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM0/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Scheduler utilities. */ extern void vPortYield( void ); #define portNVIC_INT_CTRL ( ( volatile uint32_t * ) 0xe000ed04 ) #define portNVIC_PENDSVSET 0x10000000 #define portYIELD() vPortYield() #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) *( portNVIC_INT_CTRL ) = portNVIC_PENDSVSET #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); extern uint32_t ulSetInterruptMaskFromISR( void ); extern void vClearInterruptMaskFromISR( uint32_t ulMask ); #define portDISABLE_INTERRUPTS() __asm volatile ( "cpsid i" ) #define portENABLE_INTERRUPTS() __asm volatile ( "cpsie i" ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x ) /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portNOP() /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Pa082 #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23/non_secure/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /* Portasm includes. */ #include "portasm.h" #if ( configENABLE_TRUSTZONE == 1 ) /* Secure components includes. */ #include "secure_context.h" #include "secure_init.h" #endif /* configENABLE_TRUSTZONE */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /** * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS * on the secure side. The following are the valid configuration seetings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 * * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 * * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 */ #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. #endif /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the SCB. */ #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the FPU. */ #define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) #define portMPU_RLAR_REGION_ENABLE ( 1UL ) /* Enable privileged access to unmapped region. */ #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /*-----------------------------------------------------------*/ /** * @brief The maximum 24-bit number. * * It is needed because the systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /** * @brief A fiddle factor to estimate the number of SysTick counts that would * have occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) /** * @brief Initial EXC_RETURN value. * * FF FF FF FD * 1111 1111 1111 1111 1111 1111 1111 1101 * * Bit[6] - 1 --> The exception was taken from the Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 1 --> The exception was taken to the Secure state. */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else /** * @brief Initial EXC_RETURN value. * * FF FF FF BC * 1111 1111 1111 1111 1111 1111 1011 1100 * * Bit[6] - 0 --> The exception was taken from the Non-Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 0 --> The exception was taken to the Non-Secure state. */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ /** * @brief CONTROL register privileged bit mask. * * Bit[0] in CONTROL register tells the privilege: * Bit[0] = 0 ==> The task is privileged. * Bit[0] = 1 ==> The task is not privileged. */ #define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) /** * @brief Initial CONTROL register values. */ #define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) #define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) /** * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /** * @brief 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /** * @brief If portPRELOAD_REGISTERS then registers will be given an initial value * when a task is created. This helps in debugging at the cost of code size. */ #define portPRELOAD_REGISTERS 1 /** * @brief A task is created without a secure context, and must call * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes * any secure calls. */ #define portNO_SECURE_CONTEXT 0 /*-----------------------------------------------------------*/ /** * @brief Used to catch tasks that attempt to return from their implementing * function. */ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) /** * @brief Setup the Memory Protection Unit (MPU). */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) /** * @brief Setup the Floating Point Unit (FPU). */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ /** * @brief Setup the timer to generate the tick interrupts. * * The implementation in this file is weak to allow application writers to * change the timer used to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /** * @brief Checks whether the current execution context is interrupt. * * @return pdTRUE if the current execution context is interrupt, pdFALSE * otherwise. */ BaseType_t xPortIsInsideInterrupt( void ); /** * @brief Yield the processor. */ void vPortYield( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ void vPortExitCritical( void ) PRIVILEGED_FUNCTION; /** * @brief SysTick handler. */ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; /** * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. */ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Saved as part of the task context to indicate which context the * task is using on the secure side. */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ #if ( configUSE_TICKLESS_IDLE == 1 ) /** * @brief The number of SysTick increments that make up one tick period. */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; /** * @brief The maximum number of tick periods that can be suppressed is * limited by the 24 bit resolution of the SysTick timer. */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; /** * @brief Compensate for the CPU cycles that pass while the SysTick is * stopped (low power functionality only). */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). Artificially force an assert() * to be triggered if configASSERT() is defined, then stop here so * application writers can catch the error. */ configASSERT( ulCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being * defined but never called. ulDummy is used purely to quieten other * warnings about code appearing after this function is called - making * ulDummy volatile makes the compiler think the function could return * and therefore not output an 'unreachable code' warning for code that * appears after it. */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; extern uint32_t * __unprivileged_flash_start__; extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* if defined( __ARMCC_VERSION ) */ /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; extern uint32_t __unprivileged_flash_start__[]; extern uint32_t __unprivileged_flash_end__[]; extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check that the MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* MAIR0 - Index 0. */ portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); /* MAIR0 - Index 1. */ portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* Setup privileged flash as Read Only so that privileged tasks can * read it but not modify. */ portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged flash as Read Only by both privileged and * unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged syscalls flash as Read Only by both privileged * and unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup RAM containing kernel data for privileged access only. */ portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Enable mem fault. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; /* Enable MPU with privileged background access i.e. unmapped * regions have privileged access. */ portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) { /* Enable non-secure access to the FPU. */ SecureInit_EnableNSFPUAccess(); } #endif /* configENABLE_TRUSTZONE */ /* CP10 = 11 ==> Full access to FPU i.e. both privileged and * unprivileged code should be able to access FPU. CP11 should be * programmed to the same value as CP10. */ *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) ); /* ASPEN = 1 ==> Hardware should automatically preserve floating point * context on exception entry and restore on exception return. * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ void vPortYield( void ) /* PRIVILEGED_FUNCTION */ { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ { portDISABLE_INTERRUPTS(); ulCriticalNesting++; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ { configASSERT( ulCriticalNesting ); ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { #if ( configENABLE_MPU == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ #endif /* configENABLE_MPU */ uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) uint32_t ulR0, ulR1; extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ #endif /* configENABLE_TRUSTZONE */ uint8_t ucSVCNumber; /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ ulPC = pulCallerStackAddress[ 6 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { #if ( configENABLE_TRUSTZONE == 1 ) case portSVC_ALLOCATE_SECURE_CONTEXT: /* R0 contains the stack size passed as parameter to the * vPortAllocateSecureContext function. */ ulR0 = pulCallerStackAddress[ 0 ]; #if ( configENABLE_MPU == 1 ) { /* Read the CONTROL register value. */ __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); /* The task that raised the SVC is privileged if Bit[0] * in the CONTROL register is 0. */ ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: /* R0 contains TCB being freed and R1 contains the secure * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) { /* De-prioritize the non-secure exceptions so that the * non-secure pendSV runs at the lowest priority. */ SecureInit_DePrioritizeNSExceptions(); /* Initialize the secure context management system. */ SecureContext_Init(); } #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_FPU == 1 ) { /* Setup the Floating Point Unit (FPU). */ prvSetupFPU(); } #endif /* configENABLE_FPU */ /* Setup the context of the first task so that the first task starts * executing. */ vRestoreContextOfFirstTask(); break; #if ( configENABLE_MPU == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the svc was raised from any of * the system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { vRaisePrivilege(); } break; #endif /* configENABLE_MPU */ default: /* Incorrect SVC call. */ configASSERT( pdFALSE ); } } /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #if ( configENABLE_MPU == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /* *INDENT-ON* */ { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #endif /* portPRELOAD_REGISTERS */ return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ prvSetupMPU(); } #endif /* configENABLE_MPU */ /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; /* Start the first task. */ vStartFirstTask(); /* Should never get here as the tasks will now be executing. Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* Setup MAIR0. */ xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ if( ulStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged * SRAM is already protected using an MPU region and ARMv8-M does * not allow overlapping MPU regions. */ if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) { xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; } else { /* Define the region that allows access to the stack. */ ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); } } /* User supplied configurable regions. */ for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) { /* If xRegions is NULL i.e. the task has not specified any MPU * region, the else part ensures that all the configurable MPU * regions are invalidated. */ if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) { /* Translate the generic region definition contained in xRegions * into the ARMv8 specific MPU settings that are then stored in * xMPUSettings. */ ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; /* Start address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ); /* RO/RW. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); } else { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); } /* XN. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); } /* End Address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { /* Attr1 in MAIR0 is configured as device memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; } else { /* Attr0 in MAIR0 is configured as normal memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; } } else { /* Invalidate the region. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; } lIndex++; } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. Interrupt Program * Status Register (IPSR) holds the exception number of the currently-executing * exception or zero for Thread mode.*/ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23/non_secure/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORT_ASM_H__ #define __PORT_ASM_H__ /* Scheduler includes. */ #include "FreeRTOS.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /** * @brief Restore the context of the first task so that the first task starts * executing. */ void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * * @note This is a privileged function and should only be called from the kenrel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Starts the first task. */ void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Disables interrupts. */ uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Enables interrupts. */ void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief PendSV Exception handler. */ void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief SVC Handler. */ void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Allocate a Secure context for the calling task. * * @param[in] ulSecureStackSize The size of the stack to be allocated on the * secure side for the calling task. */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); /** * @brief Free the task's secure context. * * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. */ void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* __PORT_ASM_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23/non_secure/portasm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C EXTERN SecureContext_SaveContext EXTERN SecureContext_LoadContext PUBLIC xIsPrivileged PUBLIC vResetPrivilege PUBLIC vPortAllocateSecureContext PUBLIC vRestoreContextOfFirstTask PUBLIC vRaisePrivilege PUBLIC vStartFirstTask PUBLIC ulSetInterruptMask PUBLIC vClearInterruptMask PUBLIC PendSV_Handler PUBLIC SVC_Handler PUBLIC vPortFreeSecureContext #if ( configENABLE_FPU == 1 ) #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif /*-----------------------------------------------------------*/ /*---------------- Unprivileged Functions -------------------*/ /*-----------------------------------------------------------*/ SECTION .text:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ xIsPrivileged: mrs r0, control /* r0 = CONTROL. */ movs r1, #1 /* r1 = 1. */ tst r0, r1 /* Perform r0 & r1 (bitwise AND) and update the conditions flag. */ beq running_privileged /* If the result of previous AND operation was 0, branch. */ movs r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ bx lr /* Return. */ running_privileged: movs r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ vResetPrivilege: mrs r0, control /* r0 = CONTROL. */ movs r1, #1 /* r1 = 1. */ orrs r0, r1 /* r0 = r0 | r1. */ msr control, r0 /* CONTROL = r0. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vPortAllocateSecureContext: svc 0 /* Secure context is allocated in the supervisor call. portSVC_ALLOCATE_SECURE_CONTEXT = 0. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ /*----------------- Privileged Functions --------------------*/ /*-----------------------------------------------------------*/ SECTION privileged_functions:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ movs r5, #1 /* r5 = 1. */ bics r4, r5 /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ str r4, [r2] /* Disable MPU. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r4, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ movs r5, #4 /* r5 = 4. */ str r5, [r2] /* Program RNR = 4. */ ldmia r3!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */ ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ stmia r4!, {r6,r7} /* Write first set of RBAR/RLAR registers. */ movs r5, #5 /* r5 = 5. */ str r5, [r2] /* Program RNR = 5. */ ldmia r3!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */ ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ stmia r4!, {r6,r7} /* Write second set of RBAR/RLAR registers. */ movs r5, #6 /* r5 = 6. */ str r5, [r2] /* Program RNR = 6. */ ldmia r3!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */ ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ stmia r4!, {r6,r7} /* Write third set of RBAR/RLAR registers. */ movs r5, #7 /* r5 = 7. */ str r5, [r2] /* Program RNR = 7. */ ldmia r3!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */ ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ stmia r4!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ movs r5, #1 /* r5 = 1. */ orrs r4, r5 /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ str r4, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ ldr r5, =xSecureContext str r1, [r5] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ msr control, r3 /* Set this task's CONTROL value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb bx r4 /* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb bx r3 /* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ vRaisePrivilege: mrs r0, control /* Read the CONTROL register. */ movs r1, #1 /* r1 = 1. */ bics r0, r1 /* Clear the bit 0. */ msr control, r0 /* Write back the new CONTROL value. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vStartFirstTask: ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ ldr r0, [r0] /* The first entry in vector table is stack pointer. */ msr msp, r0 /* Set the MSP back to the start of the stack. */ cpsie i /* Globally enable interrupts. */ dsb isb svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ /*-----------------------------------------------------------*/ ulSetInterruptMask: mrs r0, PRIMASK cpsid i bx lr /*-----------------------------------------------------------*/ vClearInterruptMask: msr PRIMASK, r0 bx lr /*-----------------------------------------------------------*/ PendSV_Handler: ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ push {r0-r2, r14} bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r0-r3} /* LR is now in r3. */ mov lr, r3 /* LR = r3. */ lsls r1, r3, #25 /* 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 /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ b select_next_task save_ns_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ adds r2, r2, #16 /* r2 = r2 + 16. */ stmia r2!, {r4-r7} /* Store the low registers that are not saved automatically. */ mov r4, r8 /* r4 = r8. */ mov r5, r9 /* r5 = r9. */ mov r6, r10 /* r6 = r10. */ mov r7, r11 /* r7 = r11. */ stmia r2!, {r4-r7} /* Store the high registers that are not saved automatically. */ mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ subs r2, r2, #48 /* r2 = r2 - 48. */ stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3-r7} /* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ mov r4, r8 /* r4 = r8. */ mov r5, r9 /* r5 = r9. */ mov r6, r10 /* r6 = r10. */ mov r7, r11 /* r7 = r11. */ stmia r2!, {r4-r7} /* Store the high registers that are not saved automatically. */ #endif /* configENABLE_MPU */ select_next_task: cpsid i bl vTaskSwitchContext cpsie i ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r3] /* Read the value of MPU_CTRL. */ movs r5, #1 /* r5 = 1. */ bics r4, r5 /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ str r4, [r3] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ str r4, [r3] /* Program MAIR0. */ ldr r4, =0xe000ed98 /* r4 = 0xe000ed98 [Location of RNR]. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ movs r5, #4 /* r5 = 4. */ str r5, [r4] /* Program RNR = 4. */ ldmia r1!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r6,r7} /* Write first set of RBAR/RLAR registers. */ movs r5, #5 /* r5 = 5. */ str r5, [r4] /* Program RNR = 5. */ ldmia r1!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r6,r7} /* Write second set of RBAR/RLAR registers. */ movs r5, #6 /* r5 = 6. */ str r5, [r4] /* Program RNR = 6. */ ldmia r1!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r6,r7} /* Write third set of RBAR/RLAR registers. */ movs r5, #7 /* r5 = 7. */ str r5, [r4] /* Program RNR = 7. */ ldmia r1!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */ ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r3] /* Read the value of MPU_CTRL. */ movs r5, #1 /* r5 = 1. */ orrs r4, r5 /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ str r4, [r3] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ msr control, r3 /* Restore the CONTROL register value for the task. */ mov lr, r4 /* LR = r4. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ push {r2, r4} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r2, r4} mov lr, r4 /* LR = r4. */ lsls r1, r4, #25 /* 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 /* 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 /* Remember the new top of stack for the task. */ bx lr #else /* configENABLE_MPU */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ push {r2, r4} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r2, r4} mov lr, r4 /* LR = r4. */ lsls r1, r4, #25 /* 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 /* 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 /* Remember the new top of stack for the task. */ bx lr #endif /* configENABLE_MPU */ restore_ns_context: adds r2, r2, #16 /* Move to the high registers. */ ldmia r2!, {r4-r7} /* Restore the high registers that are not automatically restored. */ mov r8, r4 /* r8 = r4. */ mov r9, r5 /* r9 = r5. */ mov r10, r6 /* r10 = r6. */ mov r11, r7 /* r11 = r7. */ msr psp, r2 /* Remember the new top of stack for the task. */ subs r2, r2, #32 /* Go back to the low registers. */ ldmia r2!, {r4-r7} /* Restore the low registers that are not automatically restored. */ bx lr /*-----------------------------------------------------------*/ SVC_Handler: movs r0, #4 mov r1, lr tst r0, r1 beq stacking_used_msp mrs r0, psp b vPortSVCHandler_C stacking_used_msp: mrs r0, msp b vPortSVCHandler_C /*-----------------------------------------------------------*/ vPortFreeSecureContext: ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ bne free_secure_context /* Branch if r1 != 0. */ bx lr /* There is no secure context (xSecureContext is NULL). */ free_secure_context: svc 1 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 1. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23/non_secure/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M23" #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Be006 #pragma diag_suppress=Pa082 /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACROCOMMON_H #define PORTMACROCOMMON_H #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_FPU #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. #endif /* configENABLE_FPU */ #ifndef configENABLE_MPU #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. #endif /* configENABLE_MPU */ #ifndef configENABLE_TRUSTZONE #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ /** * @brief Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif #define portHAS_STACK_OVERFLOW_CHECKING 1 /*-----------------------------------------------------------*/ /** * @brief Extern declarations. */ extern BaseType_t xPortIsInsideInterrupt( void ); extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; #if ( configENABLE_TRUSTZONE == 1 ) extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_MPU == 1 ) extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief MPU specific constants. */ #if ( configENABLE_MPU == 1 ) #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #else #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* MPU regions. */ #define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_RAM_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ /* Device memory attributes used in MPU_MAIR registers. * * 8-bit values encoded as follows: * Bit[7:4] - 0000 - Device Memory * Bit[3:2] - 00 --> Device-nGnRnE * 01 --> Device-nGnRE * 10 --> Device-nGRE * 11 --> Device-GRE * Bit[1:0] - 00, Reserved. */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ /* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ /* Attributes used in MPU_RBAR registers. */ #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ /** * @brief Settings to define an MPU region. */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */ } MPURegionSettings_t; /** * @brief MPU settings as stored in the TCB. */ typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ } xMPU_SETTINGS; /*-----------------------------------------------------------*/ /** * @brief SVC numbers. */ #define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 /*-----------------------------------------------------------*/ /** * @brief Scheduler utilities. */ #define portYIELD() vPortYield() #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /** * @brief Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /** * @brief Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Allocate a secure context for the task. * * 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 context before it calls any secure function. * * @param[in] ulSecureStackSize The size of the secure stack to be allocated. */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) /** * @brief Called when a task is deleted to delete the task's secure context, * if it has one. * * @param[in] pxTCB The TCB of the task being deleted. */ #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. * * 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, * the privilege is not raised. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() #else #define portIS_PRIVILEGED() #define portRAISE_PRIVILEGE() #define portRESET_PRIVILEGE() #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief Barriers. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACROCOMMON_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23/secure/secure_context.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Secure context includes. */ #include "secure_context.h" /* Secure heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief CONTROL value for privileged tasks. * * Bit[0] - 0 --> Thread mode is privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_PRIVILEGED 0x02 /** * @brief CONTROL value for un-privileged tasks. * * Bit[0] - 1 --> Thread mode is un-privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 /** * @brief Size of stack seal values in bytes. */ #define securecontextSTACK_SEAL_SIZE 8 /** * @brief Stack seal value as recommended by ARM. */ #define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5 /** * @brief Maximum number of secure contexts. */ #ifndef secureconfigMAX_SECURE_CONTEXTS #define secureconfigMAX_SECURE_CONTEXTS 8UL #endif /*-----------------------------------------------------------*/ /** * @brief Pre-allocated array of secure contexts. */ SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ]; /*-----------------------------------------------------------*/ /** * @brief Get a free secure context for a task from the secure context pool (xSecureContexts). * * This function ensures that only one secure context is allocated for a task. * * @param[in] pvTaskHandle The task handle for which the secure context is allocated. * * @return Index of a free secure context in the xSecureContexts array. */ static uint32_t ulGetSecureContext( void * pvTaskHandle ); /** * @brief Return the secure context to the secure context pool (xSecureContexts). * * @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array. */ static void vReturnSecureContext( uint32_t ulSecureContextIndex ); /* These are implemented in assembly. */ extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ); extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ); /*-----------------------------------------------------------*/ static uint32_t ulGetSecureContext( void * pvTaskHandle ) { /* Start with invalid index. */ uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) && ( xSecureContexts[ i ].pucStackLimit == NULL ) && ( xSecureContexts[ i ].pucStackStart == NULL ) && ( xSecureContexts[ i ].pvTaskHandle == NULL ) && ( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = i; } else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle ) { /* A task can only have one secure context. Do not allocate a second * context for the same task. */ ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; break; } } return ulSecureContextIndex; } /*-----------------------------------------------------------*/ static void vReturnSecureContext( uint32_t ulSecureContextIndex ) { xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) { uint32_t ulIPSR, i; static uint32_t ulSecureContextsInitialized = 0; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) ) { /* Ensure to initialize secure contexts only once. */ ulSecureContextsInitialized = 1; /* No stack for thread mode until a task's context is loaded. */ secureportSET_PSPLIM( securecontextNO_STACK ); secureportSET_PSP( securecontextNO_STACK ); /* Initialize all secure contexts. */ for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { xSecureContexts[ i ].pucCurrentStackPointer = NULL; xSecureContexts[ i ].pucStackLimit = NULL; xSecureContexts[ i ].pucStackStart = NULL; xSecureContexts[ i ].pvTaskHandle = NULL; } #if ( configENABLE_MPU == 1 ) { /* Configure thread mode to use PSP and to be unprivileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED ); } #else /* configENABLE_MPU */ { /* Configure thread mode to use PSP and to be privileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED ); } #endif /* configENABLE_MPU */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ) #else /* configENABLE_MPU */ secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ) #endif /* configENABLE_MPU */ { uint8_t * pucStackMemory = NULL; uint8_t * pucStackLimit; uint32_t ulIPSR, ulSecureContextIndex; SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID; #if ( configENABLE_MPU == 1 ) uint32_t * pulCurrentStackPointer = NULL; #endif /* configENABLE_MPU */ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit * Register (PSPLIM) value. */ secureportREAD_IPSR( ulIPSR ); secureportREAD_PSPLIM( pucStackLimit ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. * Also do nothing, if a secure context us already loaded. PSPLIM is set to * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { /* Ontain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space. */ pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE ); if( pucStackMemory != NULL ) { /* Since stack grows down, the starting point will be the last * location. Note that this location is next to the last * allocated byte for stack (excluding the space for seal values) * because the hardware decrements the stack pointer before * writing i.e. if stack pointer is 0x2, a push operation will * decrement the stack pointer to 0x1 and then write at 0x1. */ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize; /* Seal the created secure process stack. */ *( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE; *( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE; /* The stack cannot go beyond this location. This value is * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle; #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 ) { *( 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 /* configENABLE_MPU */ { /* Current SP is set to the starting of the stack. This * value programmed in the PSP register on context switch. */ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart; } #endif /* configENABLE_MPU */ /* Ensure to never return 0 as a valid context handle. */ xSecureContextHandle = ulSecureContextIndex + 1UL; } } } return xSecureContextHandle; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint32_t ulIPSR, ulSecureContextIndex; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* Only free if a valid context handle is passed. */ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; /* Ensure that the secure context being deleted is associated with * the task. */ if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) { /* Free the stack space. */ vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); /* Return the secure context back to the free secure contexts pool. */ vReturnSecureContext( ulSecureContextIndex ); } } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that no secure context is loaded and the task is loading it's * own context. */ if( ( pucStackLimit == securecontextNO_STACK ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that task's context is loaded and the task is saving it's own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23/secure/secure_context.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_CONTEXT_H__ #define __SECURE_CONTEXT_H__ /* Standard includes. */ #include /* FreeRTOS includes. */ #include "FreeRTOSConfig.h" /** * @brief PSP value when no secure context is loaded. */ #define securecontextNO_STACK 0x0 /** * @brief Invalid context ID. */ #define securecontextINVALID_CONTEXT_ID 0UL /*-----------------------------------------------------------*/ /** * @brief Structure to represent a secure context. * * @note Since stack grows down, pucStackStart is the highest address while * pucStackLimit is the first address of the allocated memory. */ typedef struct SecureContext { uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */ uint8_t * pucStackStart; /**< First location of the stack memory. */ void * pvTaskHandle; /**< Task handle of the task this context is associated with. */ } SecureContext_t; /*-----------------------------------------------------------*/ /** * @brief Opaque handle for a secure context. */ typedef uint32_t SecureContextHandle_t; /*-----------------------------------------------------------*/ /** * @brief Initializes the secure context management system. * * PSP is set to NULL and therefore a task must allocate and load a context * before calling any secure side function in the thread mode. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureContext_Init( void ); /** * @brief Allocates a context on the secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] ulSecureStackSize Size of the stack to allocate on secure side. * @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise. * * @return Opaque context handle if context is successfully allocated, NULL * otherwise. */ #if ( configENABLE_MPU == 1 ) SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ); #else /* configENABLE_MPU */ SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ); #endif /* configENABLE_MPU */ /** * @brief Frees the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the * context to be freed. */ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Loads the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be loaded. */ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Saves the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be saved. */ void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); #endif /* __SECURE_CONTEXT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23/secure/secure_context_port_asm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ SECTION .text:CODE:NOROOT(2) THUMB /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" PUBLIC SecureContext_LoadContextAsm PUBLIC SecureContext_SaveContextAsm #if ( configENABLE_FPU == 1 ) #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif /*-----------------------------------------------------------*/ SecureContext_LoadContextAsm: /* pxSecureContext value is in r0. */ mrs r1, ipsr /* r1 = IPSR. */ cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ ldmia r0!, {r1, r2} /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */ #if ( configENABLE_MPU == 1 ) ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */ msr control, r3 /* CONTROL = r3. */ #endif /* configENABLE_MPU */ msr psplim, r2 /* PSPLIM = r2. */ msr psp, r1 /* PSP = r1. */ load_ctx_therad_mode: bx lr /*-----------------------------------------------------------*/ SecureContext_SaveContextAsm: /* pxSecureContext value is in r0. */ mrs r1, ipsr /* r1 = IPSR. */ cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ mrs r1, psp /* r1 = PSP. */ #if ( configENABLE_MPU == 1 ) mrs r2, control /* r2 = CONTROL. */ subs r1, r1, #4 /* Make space for the CONTROL value on the stack. */ str r1, [r0] /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ stmia r1!, {r2} /* Store CONTROL value on the stack. */ #else /* configENABLE_MPU */ str r1, [r0] /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ #endif /* configENABLE_MPU */ movs r1, #0 /* r1 = securecontextNO_STACK. */ msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */ msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */ save_ctx_therad_mode: bx lr /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23/secure/secure_heap.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure context heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Total heap size. */ #ifndef secureconfigTOTAL_HEAP_SIZE #define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) ) #endif /* No test marker by default. */ #ifndef mtCOVERAGE_TEST_MARKER #define mtCOVERAGE_TEST_MARKER() #endif /* No tracing by default. */ #ifndef traceMALLOC #define traceMALLOC( pvReturn, xWantedSize ) #endif /* No tracing by default. */ #ifndef traceFREE #define traceFREE( pv, xBlockSize ) #endif /* Block sizes must not get too small. */ #define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) /* Assumes 8bit bytes! */ #define secureheapBITS_PER_BYTE ( ( size_t ) 8 ) /*-----------------------------------------------------------*/ /* Allocate the memory for the heap. */ #if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) /* The application writer has already defined the array used for the RTOS * heap - probably so it can be placed in a special segment or address. */ extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #else /* configAPPLICATION_ALLOCATED_HEAP */ static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #endif /* configAPPLICATION_ALLOCATED_HEAP */ /** * @brief The linked list structure. * * This is used to link free blocks in order of their memory address. */ typedef struct A_BLOCK_LINK { struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */ size_t xBlockSize; /**< The size of the free block. */ } BlockLink_t; /*-----------------------------------------------------------*/ /** * @brief Called automatically to setup the required heap structures the first * time pvPortMalloc() is called. */ static void prvHeapInit( void ); /** * @brief Inserts a block of memory that is being freed into the correct * position in the list of free memory blocks. * * The block being freed will be merged with the block in front it and/or the * block behind it if the memory blocks are adjacent to each other. * * @param[in] pxBlockToInsert The block being freed. */ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ); /*-----------------------------------------------------------*/ /** * @brief The size of the structure placed at the beginning of each allocated * memory block must by correctly byte aligned. */ static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); /** * @brief Create a couple of list links to mark the start and end of the list. */ static BlockLink_t xStart; static BlockLink_t * pxEnd = NULL; /** * @brief Keeps track of the number of free bytes remaining, but says nothing * about fragmentation. */ static size_t xFreeBytesRemaining = 0U; static size_t xMinimumEverFreeBytesRemaining = 0U; /** * @brief Gets set to the top bit of an size_t type. * * When this bit in the xBlockSize member of an BlockLink_t structure is set * then the block belongs to the application. When the bit is free the block is * still part of the free heap space. */ static size_t xBlockAllocatedBit = 0; /*-----------------------------------------------------------*/ static void prvHeapInit( void ) { BlockLink_t * pxFirstFreeBlock; uint8_t * pucAlignedHeap; size_t uxAddress; size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE; /* Ensure the heap starts on a correctly aligned boundary. */ uxAddress = ( size_t ) ucHeap; if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 ) { uxAddress += ( secureportBYTE_ALIGNMENT - 1 ); uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; } pucAlignedHeap = ( uint8_t * ) uxAddress; /* xStart is used to hold a pointer to the first item in the list of free * blocks. The void cast is used to prevent compiler warnings. */ xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; xStart.xBlockSize = ( size_t ) 0; /* pxEnd is used to mark the end of the list of free blocks and is inserted * at the end of the heap space. */ uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; uxAddress -= xHeapStructSize; uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); pxEnd = ( void * ) uxAddress; pxEnd->xBlockSize = 0; pxEnd->pxNextFreeBlock = NULL; /* To start with there is a single free block that is sized to take up the * entire heap space, minus the space taken by pxEnd. */ pxFirstFreeBlock = ( void * ) pucAlignedHeap; pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; pxFirstFreeBlock->pxNextFreeBlock = pxEnd; /* Only one block exists - and it covers the entire usable heap space. */ xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; /* Work out the position of the top bit in a size_t variable. */ xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 ); } /*-----------------------------------------------------------*/ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) { BlockLink_t * pxIterator; uint8_t * puc; /* Iterate through the list until a block is found that has a higher address * than the block being inserted. */ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) { /* Nothing to do here, just iterate to the right position. */ } /* Do the block being inserted, and the block it is being inserted after * make a contiguous block of memory? */ puc = ( uint8_t * ) pxIterator; if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) { pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; pxBlockToInsert = pxIterator; } else { mtCOVERAGE_TEST_MARKER(); } /* Do the block being inserted, and the block it is being inserted before * make a contiguous block of memory? */ puc = ( uint8_t * ) pxBlockToInsert; if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) { if( pxIterator->pxNextFreeBlock != pxEnd ) { /* Form one big block from the two blocks. */ pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; } else { pxBlockToInsert->pxNextFreeBlock = pxEnd; } } else { pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } /* If the block being inserted plugged a gab, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ if( pxIterator != pxBlockToInsert ) { pxIterator->pxNextFreeBlock = pxBlockToInsert; } else { mtCOVERAGE_TEST_MARKER(); } } /*-----------------------------------------------------------*/ void * pvPortMalloc( size_t xWantedSize ) { BlockLink_t * pxBlock; BlockLink_t * pxPreviousBlock; BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ if( pxEnd == NULL ) { prvHeapInit(); } else { mtCOVERAGE_TEST_MARKER(); } /* Check the requested block size is not so large that the top bit is set. * The top bit of the block size member of the BlockLink_t structure is used * to determine who owns the block - the application or the kernel, so it * must be free. */ if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) { /* The wanted size is increased so it can contain a BlockLink_t * structure in addition to the requested amount of bytes. */ if( xWantedSize > 0 ) { xWantedSize += xHeapStructSize; /* Ensure that blocks are always aligned to the required number of * bytes. */ if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 ) { /* Byte alignment required. */ xWantedSize += ( secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) ); secureportASSERT( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) == 0 ); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) { /* Traverse the list from the start (lowest address) block until * one of adequate size is found. */ pxPreviousBlock = &xStart; pxBlock = xStart.pxNextFreeBlock; while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) { pxPreviousBlock = pxBlock; pxBlock = pxBlock->pxNextFreeBlock; } /* If the end marker was reached then a block of adequate size was * not found. */ if( pxBlock != pxEnd ) { /* Return the memory space pointed to - jumping over the * BlockLink_t structure at its start. */ pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); /* This block is being returned for use so must be taken out * of the list of free blocks. */ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; /* If the block is larger than required it can be split into * two. */ if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE ) { /* This block is to be split into two. Create a new * block following the number of bytes requested. The void * cast is used to prevent byte alignment warnings from the * compiler. */ pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 ); /* Calculate the sizes of two blocks split from the single * block. */ pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; pxBlock->xBlockSize = xWantedSize; /* Insert the new block into the list of free blocks. */ prvInsertBlockIntoFreeList( pxNewBlockLink ); } else { mtCOVERAGE_TEST_MARKER(); } xFreeBytesRemaining -= pxBlock->xBlockSize; if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) { xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; } else { mtCOVERAGE_TEST_MARKER(); } /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ pxBlock->xBlockSize |= xBlockAllocatedBit; pxBlock->pxNextFreeBlock = NULL; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } traceMALLOC( pvReturn, xWantedSize ); #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { extern void vApplicationMallocFailedHook( void ); vApplicationMallocFailedHook(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */ secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 ); return pvReturn; } /*-----------------------------------------------------------*/ void vPortFree( void * pv ) { uint8_t * puc = ( uint8_t * ) pv; BlockLink_t * pxLink; if( pv != NULL ) { /* The memory being freed will have an BlockLink_t structure immediately * before it. */ puc -= xHeapStructSize; /* This casting is to keep the compiler from issuing warnings. */ pxLink = ( void * ) puc; /* Check the block is actually allocated. */ secureportASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); secureportASSERT( pxLink->pxNextFreeBlock == NULL ); if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) { if( pxLink->pxNextFreeBlock == NULL ) { /* The block is being returned to the heap - it is no longer * allocated. */ pxLink->xBlockSize &= ~xBlockAllocatedBit; secureportDISABLE_NON_SECURE_INTERRUPTS(); { /* Add this block to the list of free blocks. */ xFreeBytesRemaining += pxLink->xBlockSize; traceFREE( pv, pxLink->xBlockSize ); prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); } secureportENABLE_NON_SECURE_INTERRUPTS(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } } /*-----------------------------------------------------------*/ size_t xPortGetFreeHeapSize( void ) { return xFreeBytesRemaining; } /*-----------------------------------------------------------*/ size_t xPortGetMinimumEverFreeHeapSize( void ) { return xMinimumEverFreeBytesRemaining; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23/secure/secure_heap.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_HEAP_H__ #define __SECURE_HEAP_H__ /* Standard includes. */ #include /** * @brief Allocates memory from heap. * * @param[in] xWantedSize The size of the memory to be allocated. * * @return Pointer to the memory region if the allocation is successful, NULL * otherwise. */ void * pvPortMalloc( size_t xWantedSize ); /** * @brief Frees the previously allocated memory. * * @param[in] pv Pointer to the memory to be freed. */ void vPortFree( void * pv ); /** * @brief Get the free heap size. * * @return Free heap size. */ size_t xPortGetFreeHeapSize( void ); /** * @brief Get the minimum ever free heap size. * * @return Minimum ever free heap size. */ size_t xPortGetMinimumEverFreeHeapSize( void ); #endif /* __SECURE_HEAP_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23/secure/secure_init.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure init includes. */ #include "secure_init.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Constants required to manipulate the SCB. */ #define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */ #define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL ) #define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS ) #define secureinitSCB_AIRCR_PRIS_POS ( 14UL ) #define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS ) /** * @brief Constants required to manipulate the FPU. */ #define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define secureinitFPCCR_LSPENS_POS ( 29UL ) #define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS ) #define secureinitFPCCR_TS_POS ( 26UL ) #define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS ) #define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */ #define secureinitNSACR_CP10_POS ( 10UL ) #define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS ) #define secureinitNSACR_CP11_POS ( 11UL ) #define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS ) /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { *( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) | ( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) | ( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK ); } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* CP10 = 1 ==> Non-secure access to the Floating Point Unit is * permitted. CP11 should be programmed to the same value as CP10. */ *( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK ); /* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures * that we can enable/disable lazy stacking in port.c file. */ *( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK ); /* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP * registers (S16-S31) are also pushed to stack on exception entry and * restored on exception return. */ *( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK ); } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23/secure/secure_init.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_INIT_H__ #define __SECURE_INIT_H__ /** * @brief De-prioritizes the non-secure exceptions. * * This is needed to ensure that the non-secure PendSV runs at the lowest * priority. Context switch is done in the non-secure PendSV handler. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_DePrioritizeNSExceptions( void ); /** * @brief Sets up the Floating Point Unit (FPU) for Non-Secure access. * * Also sets FPCCR.TS=1 to ensure that the content of the Floating Point * Registers are not leaked to the non-secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_EnableNSFPUAccess( void ); #endif /* __SECURE_INIT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23/secure/secure_port_macros.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_PORT_MACROS_H__ #define __SECURE_PORT_MACROS_H__ /** * @brief Byte alignment requirements. */ #define secureportBYTE_ALIGNMENT 8 #define secureportBYTE_ALIGNMENT_MASK ( 0x0007 ) /** * @brief Macro to declare a function as non-secure callable. */ #if defined( __IAR_SYSTEMS_ICC__ ) #define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root #else #define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) ) #endif /** * @brief Set the secure PRIMASK value. */ #define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Set the non-secure PRIMASK value. */ #define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Read the PSP value in the given variable. */ #define secureportREAD_PSP( pucOutCurrentStackPointer ) \ __asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) ) /** * @brief Set the PSP to the given value. */ #define secureportSET_PSP( pucCurrentStackPointer ) \ __asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) ) /** * @brief Read the PSPLIM value in the given variable. */ #define secureportREAD_PSPLIM( pucOutStackLimit ) \ __asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) ) /** * @brief Set the PSPLIM to the given value. */ #define secureportSET_PSPLIM( pucStackLimit ) \ __asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) ) /** * @brief Set the NonSecure MSP to the given value. */ #define secureportSET_MSP_NS( pucMainStackPointer ) \ __asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) ) /** * @brief Set the CONTROL register to the given value. */ #define secureportSET_CONTROL( ulControl ) \ __asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" ) /** * @brief Read the Interrupt Program Status Register (IPSR) value in the given * variable. */ #define secureportREAD_IPSR( ulIPSR ) \ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) ) /** * @brief PRIMASK value to enable interrupts. */ #define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0 /** * @brief PRIMASK value to disable interrupts. */ #define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1 /** * @brief Disable secure interrupts. */ #define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Disable non-secure interrupts. * * This effectively disables context switches. */ #define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Enable non-secure interrupts. */ #define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL ) /** * @brief Assert definition. */ #define secureportASSERT( x ) \ if( ( x ) == 0 ) \ { \ secureportDISABLE_SECURE_INTERRUPTS(); \ secureportDISABLE_NON_SECURE_INTERRUPTS(); \ for( ; ; ) {; } \ } #endif /* __SECURE_PORT_MACROS_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23_NTZ/non_secure/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /* Portasm includes. */ #include "portasm.h" #if ( configENABLE_TRUSTZONE == 1 ) /* Secure components includes. */ #include "secure_context.h" #include "secure_init.h" #endif /* configENABLE_TRUSTZONE */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /** * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS * on the secure side. The following are the valid configuration seetings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 * * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 * * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 */ #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. #endif /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the SCB. */ #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the FPU. */ #define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) #define portMPU_RLAR_REGION_ENABLE ( 1UL ) /* Enable privileged access to unmapped region. */ #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /*-----------------------------------------------------------*/ /** * @brief The maximum 24-bit number. * * It is needed because the systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /** * @brief A fiddle factor to estimate the number of SysTick counts that would * have occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) /** * @brief Initial EXC_RETURN value. * * FF FF FF FD * 1111 1111 1111 1111 1111 1111 1111 1101 * * Bit[6] - 1 --> The exception was taken from the Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 1 --> The exception was taken to the Secure state. */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else /** * @brief Initial EXC_RETURN value. * * FF FF FF BC * 1111 1111 1111 1111 1111 1111 1011 1100 * * Bit[6] - 0 --> The exception was taken from the Non-Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 0 --> The exception was taken to the Non-Secure state. */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ /** * @brief CONTROL register privileged bit mask. * * Bit[0] in CONTROL register tells the privilege: * Bit[0] = 0 ==> The task is privileged. * Bit[0] = 1 ==> The task is not privileged. */ #define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) /** * @brief Initial CONTROL register values. */ #define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) #define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) /** * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /** * @brief 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /** * @brief If portPRELOAD_REGISTERS then registers will be given an initial value * when a task is created. This helps in debugging at the cost of code size. */ #define portPRELOAD_REGISTERS 1 /** * @brief A task is created without a secure context, and must call * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes * any secure calls. */ #define portNO_SECURE_CONTEXT 0 /*-----------------------------------------------------------*/ /** * @brief Used to catch tasks that attempt to return from their implementing * function. */ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) /** * @brief Setup the Memory Protection Unit (MPU). */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) /** * @brief Setup the Floating Point Unit (FPU). */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ /** * @brief Setup the timer to generate the tick interrupts. * * The implementation in this file is weak to allow application writers to * change the timer used to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /** * @brief Checks whether the current execution context is interrupt. * * @return pdTRUE if the current execution context is interrupt, pdFALSE * otherwise. */ BaseType_t xPortIsInsideInterrupt( void ); /** * @brief Yield the processor. */ void vPortYield( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ void vPortExitCritical( void ) PRIVILEGED_FUNCTION; /** * @brief SysTick handler. */ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; /** * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. */ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Saved as part of the task context to indicate which context the * task is using on the secure side. */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ #if ( configUSE_TICKLESS_IDLE == 1 ) /** * @brief The number of SysTick increments that make up one tick period. */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; /** * @brief The maximum number of tick periods that can be suppressed is * limited by the 24 bit resolution of the SysTick timer. */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; /** * @brief Compensate for the CPU cycles that pass while the SysTick is * stopped (low power functionality only). */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). Artificially force an assert() * to be triggered if configASSERT() is defined, then stop here so * application writers can catch the error. */ configASSERT( ulCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being * defined but never called. ulDummy is used purely to quieten other * warnings about code appearing after this function is called - making * ulDummy volatile makes the compiler think the function could return * and therefore not output an 'unreachable code' warning for code that * appears after it. */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; extern uint32_t * __unprivileged_flash_start__; extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* if defined( __ARMCC_VERSION ) */ /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; extern uint32_t __unprivileged_flash_start__[]; extern uint32_t __unprivileged_flash_end__[]; extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check that the MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* MAIR0 - Index 0. */ portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); /* MAIR0 - Index 1. */ portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* Setup privileged flash as Read Only so that privileged tasks can * read it but not modify. */ portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged flash as Read Only by both privileged and * unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged syscalls flash as Read Only by both privileged * and unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup RAM containing kernel data for privileged access only. */ portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Enable mem fault. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; /* Enable MPU with privileged background access i.e. unmapped * regions have privileged access. */ portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) { /* Enable non-secure access to the FPU. */ SecureInit_EnableNSFPUAccess(); } #endif /* configENABLE_TRUSTZONE */ /* CP10 = 11 ==> Full access to FPU i.e. both privileged and * unprivileged code should be able to access FPU. CP11 should be * programmed to the same value as CP10. */ *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) ); /* ASPEN = 1 ==> Hardware should automatically preserve floating point * context on exception entry and restore on exception return. * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ void vPortYield( void ) /* PRIVILEGED_FUNCTION */ { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ { portDISABLE_INTERRUPTS(); ulCriticalNesting++; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ { configASSERT( ulCriticalNesting ); ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { #if ( configENABLE_MPU == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ #endif /* configENABLE_MPU */ uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) uint32_t ulR0, ulR1; extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ #endif /* configENABLE_TRUSTZONE */ uint8_t ucSVCNumber; /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ ulPC = pulCallerStackAddress[ 6 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { #if ( configENABLE_TRUSTZONE == 1 ) case portSVC_ALLOCATE_SECURE_CONTEXT: /* R0 contains the stack size passed as parameter to the * vPortAllocateSecureContext function. */ ulR0 = pulCallerStackAddress[ 0 ]; #if ( configENABLE_MPU == 1 ) { /* Read the CONTROL register value. */ __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); /* The task that raised the SVC is privileged if Bit[0] * in the CONTROL register is 0. */ ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: /* R0 contains TCB being freed and R1 contains the secure * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) { /* De-prioritize the non-secure exceptions so that the * non-secure pendSV runs at the lowest priority. */ SecureInit_DePrioritizeNSExceptions(); /* Initialize the secure context management system. */ SecureContext_Init(); } #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_FPU == 1 ) { /* Setup the Floating Point Unit (FPU). */ prvSetupFPU(); } #endif /* configENABLE_FPU */ /* Setup the context of the first task so that the first task starts * executing. */ vRestoreContextOfFirstTask(); break; #if ( configENABLE_MPU == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the svc was raised from any of * the system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { vRaisePrivilege(); } break; #endif /* configENABLE_MPU */ default: /* Incorrect SVC call. */ configASSERT( pdFALSE ); } } /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #if ( configENABLE_MPU == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /* *INDENT-ON* */ { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #endif /* portPRELOAD_REGISTERS */ return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ prvSetupMPU(); } #endif /* configENABLE_MPU */ /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; /* Start the first task. */ vStartFirstTask(); /* Should never get here as the tasks will now be executing. Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* Setup MAIR0. */ xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ if( ulStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged * SRAM is already protected using an MPU region and ARMv8-M does * not allow overlapping MPU regions. */ if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) { xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; } else { /* Define the region that allows access to the stack. */ ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); } } /* User supplied configurable regions. */ for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) { /* If xRegions is NULL i.e. the task has not specified any MPU * region, the else part ensures that all the configurable MPU * regions are invalidated. */ if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) { /* Translate the generic region definition contained in xRegions * into the ARMv8 specific MPU settings that are then stored in * xMPUSettings. */ ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; /* Start address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ); /* RO/RW. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); } else { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); } /* XN. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); } /* End Address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { /* Attr1 in MAIR0 is configured as device memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; } else { /* Attr0 in MAIR0 is configured as normal memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; } } else { /* Invalidate the region. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; } lIndex++; } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. Interrupt Program * Status Register (IPSR) holds the exception number of the currently-executing * exception or zero for Thread mode.*/ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORT_ASM_H__ #define __PORT_ASM_H__ /* Scheduler includes. */ #include "FreeRTOS.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /** * @brief Restore the context of the first task so that the first task starts * executing. */ void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * * @note This is a privileged function and should only be called from the kenrel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Starts the first task. */ void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Disables interrupts. */ uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Enables interrupts. */ void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief PendSV Exception handler. */ void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief SVC Handler. */ void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Allocate a Secure context for the calling task. * * @param[in] ulSecureStackSize The size of the stack to be allocated on the * secure side for the calling task. */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); /** * @brief Free the task's secure context. * * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. */ void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* __PORT_ASM_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" EXTERN pxCurrentTCB EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C PUBLIC xIsPrivileged PUBLIC vResetPrivilege PUBLIC vRestoreContextOfFirstTask PUBLIC vRaisePrivilege PUBLIC vStartFirstTask PUBLIC ulSetInterruptMask PUBLIC vClearInterruptMask PUBLIC PendSV_Handler PUBLIC SVC_Handler #if ( configENABLE_FPU == 1 ) #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif /*-----------------------------------------------------------*/ /*---------------- Unprivileged Functions -------------------*/ /*-----------------------------------------------------------*/ SECTION .text:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ xIsPrivileged: mrs r0, control /* r0 = CONTROL. */ movs r1, #1 /* r1 = 1. */ tst r0, r1 /* Perform r0 & r1 (bitwise AND) and update the conditions flag. */ beq running_privileged /* If the result of previous AND operation was 0, branch. */ movs r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ bx lr /* Return. */ running_privileged: movs r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ vResetPrivilege: mrs r0, control /* r0 = CONTROL. */ movs r1, #1 /* r1 = 1. */ orrs r0, r1 /* r0 = r0 | r1. */ msr control, r0 /* CONTROL = r0. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ /*----------------- Privileged Functions --------------------*/ /*-----------------------------------------------------------*/ SECTION privileged_functions:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r3, [r2] /* Read the value of MPU_CTRL. */ movs r4, #1 /* r4 = 1. */ bics r3, r4 /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ str r3, [r2] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r4, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ movs r4, #4 /* r4 = 4. */ str r4, [r2] /* Program RNR = 4. */ ldmia r1!, {r5,r6} /* Read first set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r5,r6} /* Write first set of RBAR/RLAR registers. */ movs r4, #5 /* r4 = 5. */ str r4, [r2] /* Program RNR = 5. */ ldmia r1!, {r5,r6} /* Read second set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r5,r6} /* Write second set of RBAR/RLAR registers. */ movs r4, #6 /* r4 = 6. */ str r4, [r2] /* Program RNR = 6. */ ldmia r1!, {r5,r6} /* Read third set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r5,r6} /* Write third set of RBAR/RLAR registers. */ movs r4, #7 /* r4 = 7. */ str r4, [r2] /* Program RNR = 7. */ ldmia r1!, {r5,r6} /* Read fourth set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r5,r6} /* Write fourth set of RBAR/RLAR registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r3, [r2] /* Read the value of MPU_CTRL. */ movs r4, #1 /* r4 = 1. */ orrs r3, r4 /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ str r3, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ msr control, r2 /* Set this task's CONTROL value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb bx r3 /* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb bx r2 /* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ vRaisePrivilege: mrs r0, control /* Read the CONTROL register. */ movs r1, #1 /* r1 = 1. */ bics r0, r1 /* Clear the bit 0. */ msr control, r0 /* Write back the new CONTROL value. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vStartFirstTask: ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ ldr r0, [r0] /* The first entry in vector table is stack pointer. */ msr msp, r0 /* Set the MSP back to the start of the stack. */ cpsie i /* Globally enable interrupts. */ dsb isb svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ nop /*-----------------------------------------------------------*/ ulSetInterruptMask: mrs r0, PRIMASK cpsid i bx lr /*-----------------------------------------------------------*/ vClearInterruptMask: msr PRIMASK, r0 bx lr /*-----------------------------------------------------------*/ PendSV_Handler: mrs r0, psp /* Read PSP in r0. */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) subs r0, r0, #44 /* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */ str r0, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mrs r2, control /* r2 = CONTROL. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r0!, {r1-r7} /* Store on the stack - PSPLIM, CONTROL, LR and low registers that are not automatically saved. */ mov r4, r8 /* r4 = r8. */ mov r5, r9 /* r5 = r9. */ mov r6, r10 /* r6 = r10. */ mov r7, r11 /* r7 = r11. */ stmia r0!, {r4-r7} /* Store the high registers that are not saved automatically. */ #else /* configENABLE_MPU */ subs r0, r0, #40 /* Make space for PSPLIM, LR and the remaining registers on the stack. */ str r0, [r1] /* Save the new top of stack in TCB. */ mrs r2, psplim /* r2 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r0!, {r2-r7} /* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */ mov r4, r8 /* r4 = r8. */ mov r5, r9 /* r5 = r9. */ mov r6, r10 /* r6 = r10. */ mov r7, r11 /* r7 = r11. */ stmia r0!, {r4-r7} /* Store the high registers that are not saved automatically. */ #endif /* configENABLE_MPU */ cpsid i bl vTaskSwitchContext cpsie i ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r3, [r2] /* Read the value of MPU_CTRL. */ movs r4, #1 /* r4 = 1. */ bics r3, r4 /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ str r3, [r2] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r4, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ movs r4, #4 /* r4 = 4. */ str r4, [r2] /* Program RNR = 4. */ ldmia r1!, {r5,r6} /* Read first set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r5,r6} /* Write first set of RBAR/RLAR registers. */ movs r4, #5 /* r4 = 5. */ str r4, [r2] /* Program RNR = 5. */ ldmia r1!, {r5,r6} /* Read second set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r5,r6} /* Write second set of RBAR/RLAR registers. */ movs r4, #6 /* r4 = 6. */ str r4, [r2] /* Program RNR = 6. */ ldmia r1!, {r5,r6} /* Read third set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r5,r6} /* Write third set of RBAR/RLAR registers. */ movs r4, #7 /* r4 = 7. */ str r4, [r2] /* Program RNR = 7. */ ldmia r1!, {r5,r6} /* Read fourth set of RBAR/RLAR from TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ stmia r3!, {r5,r6} /* Write fourth set of RBAR/RLAR registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r3, [r2] /* Read the value of MPU_CTRL. */ movs r4, #1 /* r4 = 1. */ orrs r3, r4 /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ str r3, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) adds r0, r0, #28 /* Move to the high registers. */ ldmia r0!, {r4-r7} /* Restore the high registers that are not automatically restored. */ mov r8, r4 /* r8 = r4. */ mov r9, r5 /* r9 = r5. */ mov r10, r6 /* r10 = r6. */ mov r11, r7 /* r11 = r7. */ msr psp, r0 /* Remember the new top of stack for the task. */ subs r0, r0, #44 /* Move to the starting of the saved context. */ ldmia r0!, {r1-r7} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ msr control, r2 /* Restore the CONTROL register value for the task. */ bx r3 #else /* configENABLE_MPU */ adds r0, r0, #24 /* Move to the high registers. */ ldmia r0!, {r4-r7} /* Restore the high registers that are not automatically restored. */ mov r8, r4 /* r8 = r4. */ mov r9, r5 /* r9 = r5. */ mov r10, r6 /* r10 = r6. */ mov r11, r7 /* r11 = r7. */ msr psp, r0 /* Remember the new top of stack for the task. */ subs r0, r0, #40 /* Move to the starting of the saved context. */ ldmia r0!, {r2-r7} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */ bx r3 #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ SVC_Handler: movs r0, #4 mov r1, lr tst r0, r1 beq stacking_used_msp mrs r0, psp b vPortSVCHandler_C stacking_used_msp: mrs r0, msp b vPortSVCHandler_C /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23_NTZ/non_secure/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M23" #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Be006 #pragma diag_suppress=Pa082 /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACROCOMMON_H #define PORTMACROCOMMON_H #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_FPU #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. #endif /* configENABLE_FPU */ #ifndef configENABLE_MPU #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. #endif /* configENABLE_MPU */ #ifndef configENABLE_TRUSTZONE #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ /** * @brief Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif #define portHAS_STACK_OVERFLOW_CHECKING 1 /*-----------------------------------------------------------*/ /** * @brief Extern declarations. */ extern BaseType_t xPortIsInsideInterrupt( void ); extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; #if ( configENABLE_TRUSTZONE == 1 ) extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_MPU == 1 ) extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief MPU specific constants. */ #if ( configENABLE_MPU == 1 ) #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #else #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* MPU regions. */ #define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_RAM_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ /* Device memory attributes used in MPU_MAIR registers. * * 8-bit values encoded as follows: * Bit[7:4] - 0000 - Device Memory * Bit[3:2] - 00 --> Device-nGnRnE * 01 --> Device-nGnRE * 10 --> Device-nGRE * 11 --> Device-GRE * Bit[1:0] - 00, Reserved. */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ /* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ /* Attributes used in MPU_RBAR registers. */ #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ /** * @brief Settings to define an MPU region. */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */ } MPURegionSettings_t; /** * @brief MPU settings as stored in the TCB. */ typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ } xMPU_SETTINGS; /*-----------------------------------------------------------*/ /** * @brief SVC numbers. */ #define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 /*-----------------------------------------------------------*/ /** * @brief Scheduler utilities. */ #define portYIELD() vPortYield() #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /** * @brief Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /** * @brief Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Allocate a secure context for the task. * * 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 context before it calls any secure function. * * @param[in] ulSecureStackSize The size of the secure stack to be allocated. */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) /** * @brief Called when a task is deleted to delete the task's secure context, * if it has one. * * @param[in] pxTCB The TCB of the task being deleted. */ #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. * * 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, * the privilege is not raised. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() #else #define portIS_PRIVILEGED() #define portRAISE_PRIVILEGE() #define portRESET_PRIVILEGE() #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief Barriers. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACROCOMMON_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM3/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM3 port. *----------------------------------------------------------*/ /* IAR includes. */ #include /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #if ( configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 ) #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ #endif /* Constants required to manipulate the core. Registers first... */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) /* ...then bits in the registers. */ #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) #define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) ) #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ #define portVECTACTIVE_MASK ( 0xFFUL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) /* The systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /* A fiddle factor to estimate the number of SysTick counts that would have * occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) /* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is * defined. The value 255 should also ensure backward compatibility. * FreeRTOS.org versions prior to V4.3.0 did not include this definition. */ #ifndef configKERNEL_INTERRUPT_PRIORITY #define configKERNEL_INTERRUPT_PRIORITY 255 #endif /* Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ); /* * Exception handlers. */ void xPortSysTickHandler( void ); /* * Start first task is a separate function so it can be tested in isolation. */ extern void vPortStartFirstTask( void ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* Each task maintains its own interrupt status in the critical nesting * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* * The number of SysTick increments that make up one tick period. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulTimerCountsForOneTick = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * The maximum number of tick periods that can be suppressed is limited by the * 24 bit resolution of the SysTick timer. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t xMaximumPossibleSuppressedTicks = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Compensate for the CPU cycles that pass while the SysTick is stopped (low * power functionality only. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. */ #if ( configASSERT_DEFINED == 1 ) static uint8_t ucMaxSysCallPriority = 0; static uint32_t ulMaxPRIGROUPValue = 0; static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). * * Artificially force an assert() to be triggered if configASSERT() is * defined, then stop here so application writers can catch the error. */ configASSERT( uxCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); for( ; ; ) { } } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API * functions can be called. ISR safe functions are those that end in * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { ulMaxPRIGROUPValue--; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); } #endif /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; /* Restore the clobbered interrupt priority register to its original * value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Start the first task. */ vPortStartFirstTask(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); uxCriticalNesting++; /* 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 * 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 * assert function also uses a critical section. */ if( uxCriticalNesting == 1 ) { configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { /* The SysTick runs at the lowest interrupt priority, so when this interrupt * executes all interrupts must be unmasked. There is therefore no need to * save and then restore the interrupt mask value as its value is already * known. */ portDISABLE_INTERRUPTS(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* A context switch is required. Context switching is performed in * the PendSV interrupt. Pend the PendSV interrupt. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portENABLE_INTERRUPTS(); } /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __weak void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __disable_interrupt(); __DSB(); __ISB(); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the __disable_interrupt() * call above. */ __enable_interrupt(); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __DSB(); __WFI(); __ISB(); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the __disable_interrupt() call above. */ __enable_interrupt(); __DSB(); __ISB(); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __disable_interrupt(); __DSB(); __ISB(); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __enable_interrupt(); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ /* * Setup the systick timer to generate the tick interrupts at the required * frequency. */ __weak void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and clear the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); } /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); /* Is the interrupt number a user defined interrupt? */ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /* Look up the interrupt's priority. */ ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Interrupts that use the FreeRTOS API must not be left at their * default priority of zero as that is the highest possible priority, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * and therefore also guaranteed to be invalid. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } /* Priority grouping: The interrupt controller (NVIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined * to be pre-emption priority bits. The following assertion will fail if * this is not the case (if some bits represent a sub-priority). * * If the application only uses CMSIS libraries for interrupt * configuration then the correct setting can be achieved on all Cortex-M * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * scheduler. Note however that some vendor specific peripheral libraries * assume a non-zero priority group setting, in which cases using a value * of zero will result in unpredictable behaviour. */ configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); } #endif /* configASSERT_DEFINED */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM3/portasm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #include RSEG CODE:CODE(2) thumb EXTERN pxCurrentTCB EXTERN vTaskSwitchContext PUBLIC xPortPendSVHandler PUBLIC vPortSVCHandler PUBLIC vPortStartFirstTask /*-----------------------------------------------------------*/ xPortPendSVHandler: mrs r0, psp isb ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */ ldr r2, [r3] stmdb r0!, {r4-r11} /* Save the remaining registers. */ str r0, [r2] /* Save the new top of stack into the first member of the TCB. */ stmdb sp!, {r3, r14} mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r0 dsb isb bl vTaskSwitchContext mov r0, #0 msr basepri, r0 ldmia sp!, {r3, r14} ldr r1, [r3] ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */ ldmia r0!, {r4-r11} /* Pop the registers. */ msr psp, r0 isb bx r14 /*-----------------------------------------------------------*/ vPortSVCHandler: /* Get the location of the current TCB. */ ldr r3, =pxCurrentTCB ldr r1, [r3] ldr r0, [r1] /* Pop the core registers. */ ldmia r0!, {r4-r11} msr psp, r0 isb mov r0, #0 msr basepri, r0 orr r14, r14, #13 bx r14 /*-----------------------------------------------------------*/ vPortStartFirstTask /* Use the NVIC offset register to locate the stack. */ ldr r0, =0xE000ED08 ldr r0, [r0] ldr r0, [r0] /* Set the msp back to the start of the stack. */ msr msp, r0 /* Call SVC to start the first task, ensuring interrupts are enabled. */ cpsie i cpsie f dsb isb svc 0 END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM3/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* IAR includes. */ #include /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Compiler directives. */ #define portWEAK_SYMBOL __attribute__( ( weak ) ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ #define portYIELD() \ { \ /* Set a PendSV to request a context switch. */ \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ __DSB(); \ __ISB(); \ } #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 ) /* Check the configuration. */ #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. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) __CLZ( ( uxReadyPriorities ) ) ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); #define portDISABLE_INTERRUPTS() \ { \ __set_BASEPRI( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \ __DSB(); \ __ISB(); \ } #define portENABLE_INTERRUPTS() __set_BASEPRI( 0 ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() #define portSET_INTERRUPT_MASK_FROM_ISR() __get_BASEPRI(); portDISABLE_INTERRUPTS() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) __set_BASEPRI( x ) /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /* 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 * (which build with all the ports) will build. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* portNOP() is not required by this port. */ #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif /*-----------------------------------------------------------*/ portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Pe191 #pragma diag_suppress=Pa082 #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33/non_secure/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /* Portasm includes. */ #include "portasm.h" #if ( configENABLE_TRUSTZONE == 1 ) /* Secure components includes. */ #include "secure_context.h" #include "secure_init.h" #endif /* configENABLE_TRUSTZONE */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /** * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS * on the secure side. The following are the valid configuration seetings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 * * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 * * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 */ #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. #endif /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the SCB. */ #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the FPU. */ #define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) #define portMPU_RLAR_REGION_ENABLE ( 1UL ) /* Enable privileged access to unmapped region. */ #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /*-----------------------------------------------------------*/ /** * @brief The maximum 24-bit number. * * It is needed because the systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /** * @brief A fiddle factor to estimate the number of SysTick counts that would * have occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) /** * @brief Initial EXC_RETURN value. * * FF FF FF FD * 1111 1111 1111 1111 1111 1111 1111 1101 * * Bit[6] - 1 --> The exception was taken from the Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 1 --> The exception was taken to the Secure state. */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else /** * @brief Initial EXC_RETURN value. * * FF FF FF BC * 1111 1111 1111 1111 1111 1111 1011 1100 * * Bit[6] - 0 --> The exception was taken from the Non-Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 0 --> The exception was taken to the Non-Secure state. */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ /** * @brief CONTROL register privileged bit mask. * * Bit[0] in CONTROL register tells the privilege: * Bit[0] = 0 ==> The task is privileged. * Bit[0] = 1 ==> The task is not privileged. */ #define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) /** * @brief Initial CONTROL register values. */ #define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) #define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) /** * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /** * @brief 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /** * @brief If portPRELOAD_REGISTERS then registers will be given an initial value * when a task is created. This helps in debugging at the cost of code size. */ #define portPRELOAD_REGISTERS 1 /** * @brief A task is created without a secure context, and must call * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes * any secure calls. */ #define portNO_SECURE_CONTEXT 0 /*-----------------------------------------------------------*/ /** * @brief Used to catch tasks that attempt to return from their implementing * function. */ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) /** * @brief Setup the Memory Protection Unit (MPU). */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) /** * @brief Setup the Floating Point Unit (FPU). */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ /** * @brief Setup the timer to generate the tick interrupts. * * The implementation in this file is weak to allow application writers to * change the timer used to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /** * @brief Checks whether the current execution context is interrupt. * * @return pdTRUE if the current execution context is interrupt, pdFALSE * otherwise. */ BaseType_t xPortIsInsideInterrupt( void ); /** * @brief Yield the processor. */ void vPortYield( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ void vPortExitCritical( void ) PRIVILEGED_FUNCTION; /** * @brief SysTick handler. */ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; /** * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. */ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Saved as part of the task context to indicate which context the * task is using on the secure side. */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ #if ( configUSE_TICKLESS_IDLE == 1 ) /** * @brief The number of SysTick increments that make up one tick period. */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; /** * @brief The maximum number of tick periods that can be suppressed is * limited by the 24 bit resolution of the SysTick timer. */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; /** * @brief Compensate for the CPU cycles that pass while the SysTick is * stopped (low power functionality only). */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). Artificially force an assert() * to be triggered if configASSERT() is defined, then stop here so * application writers can catch the error. */ configASSERT( ulCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being * defined but never called. ulDummy is used purely to quieten other * warnings about code appearing after this function is called - making * ulDummy volatile makes the compiler think the function could return * and therefore not output an 'unreachable code' warning for code that * appears after it. */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; extern uint32_t * __unprivileged_flash_start__; extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* if defined( __ARMCC_VERSION ) */ /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; extern uint32_t __unprivileged_flash_start__[]; extern uint32_t __unprivileged_flash_end__[]; extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check that the MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* MAIR0 - Index 0. */ portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); /* MAIR0 - Index 1. */ portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* Setup privileged flash as Read Only so that privileged tasks can * read it but not modify. */ portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged flash as Read Only by both privileged and * unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged syscalls flash as Read Only by both privileged * and unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup RAM containing kernel data for privileged access only. */ portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Enable mem fault. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; /* Enable MPU with privileged background access i.e. unmapped * regions have privileged access. */ portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) { /* Enable non-secure access to the FPU. */ SecureInit_EnableNSFPUAccess(); } #endif /* configENABLE_TRUSTZONE */ /* CP10 = 11 ==> Full access to FPU i.e. both privileged and * unprivileged code should be able to access FPU. CP11 should be * programmed to the same value as CP10. */ *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) ); /* ASPEN = 1 ==> Hardware should automatically preserve floating point * context on exception entry and restore on exception return. * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ void vPortYield( void ) /* PRIVILEGED_FUNCTION */ { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ { portDISABLE_INTERRUPTS(); ulCriticalNesting++; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ { configASSERT( ulCriticalNesting ); ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { #if ( configENABLE_MPU == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ #endif /* configENABLE_MPU */ uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) uint32_t ulR0, ulR1; extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ #endif /* configENABLE_TRUSTZONE */ uint8_t ucSVCNumber; /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ ulPC = pulCallerStackAddress[ 6 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { #if ( configENABLE_TRUSTZONE == 1 ) case portSVC_ALLOCATE_SECURE_CONTEXT: /* R0 contains the stack size passed as parameter to the * vPortAllocateSecureContext function. */ ulR0 = pulCallerStackAddress[ 0 ]; #if ( configENABLE_MPU == 1 ) { /* Read the CONTROL register value. */ __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); /* The task that raised the SVC is privileged if Bit[0] * in the CONTROL register is 0. */ ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: /* R0 contains TCB being freed and R1 contains the secure * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) { /* De-prioritize the non-secure exceptions so that the * non-secure pendSV runs at the lowest priority. */ SecureInit_DePrioritizeNSExceptions(); /* Initialize the secure context management system. */ SecureContext_Init(); } #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_FPU == 1 ) { /* Setup the Floating Point Unit (FPU). */ prvSetupFPU(); } #endif /* configENABLE_FPU */ /* Setup the context of the first task so that the first task starts * executing. */ vRestoreContextOfFirstTask(); break; #if ( configENABLE_MPU == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the svc was raised from any of * the system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { vRaisePrivilege(); } break; #endif /* configENABLE_MPU */ default: /* Incorrect SVC call. */ configASSERT( pdFALSE ); } } /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #if ( configENABLE_MPU == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /* *INDENT-ON* */ { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #endif /* portPRELOAD_REGISTERS */ return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ prvSetupMPU(); } #endif /* configENABLE_MPU */ /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; /* Start the first task. */ vStartFirstTask(); /* Should never get here as the tasks will now be executing. Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* Setup MAIR0. */ xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ if( ulStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged * SRAM is already protected using an MPU region and ARMv8-M does * not allow overlapping MPU regions. */ if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) { xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; } else { /* Define the region that allows access to the stack. */ ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); } } /* User supplied configurable regions. */ for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) { /* If xRegions is NULL i.e. the task has not specified any MPU * region, the else part ensures that all the configurable MPU * regions are invalidated. */ if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) { /* Translate the generic region definition contained in xRegions * into the ARMv8 specific MPU settings that are then stored in * xMPUSettings. */ ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; /* Start address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ); /* RO/RW. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); } else { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); } /* XN. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); } /* End Address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { /* Attr1 in MAIR0 is configured as device memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; } else { /* Attr0 in MAIR0 is configured as normal memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; } } else { /* Invalidate the region. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; } lIndex++; } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. Interrupt Program * Status Register (IPSR) holds the exception number of the currently-executing * exception or zero for Thread mode.*/ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33/non_secure/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORT_ASM_H__ #define __PORT_ASM_H__ /* Scheduler includes. */ #include "FreeRTOS.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /** * @brief Restore the context of the first task so that the first task starts * executing. */ void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * * @note This is a privileged function and should only be called from the kenrel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Starts the first task. */ void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Disables interrupts. */ uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Enables interrupts. */ void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief PendSV Exception handler. */ void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief SVC Handler. */ void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Allocate a Secure context for the calling task. * * @param[in] ulSecureStackSize The size of the stack to be allocated on the * secure side for the calling task. */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); /** * @brief Free the task's secure context. * * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. */ void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* __PORT_ASM_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33/non_secure/portasm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C EXTERN SecureContext_SaveContext EXTERN SecureContext_LoadContext PUBLIC xIsPrivileged PUBLIC vResetPrivilege PUBLIC vPortAllocateSecureContext PUBLIC vRestoreContextOfFirstTask PUBLIC vRaisePrivilege PUBLIC vStartFirstTask PUBLIC ulSetInterruptMask PUBLIC vClearInterruptMask PUBLIC PendSV_Handler PUBLIC SVC_Handler PUBLIC vPortFreeSecureContext /*-----------------------------------------------------------*/ /*---------------- Unprivileged Functions -------------------*/ /*-----------------------------------------------------------*/ SECTION .text:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ xIsPrivileged: mrs r0, control /* r0 = CONTROL. */ tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ ite ne movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ vResetPrivilege: mrs r0, control /* r0 = CONTROL. */ orr r0, r0, #1 /* r0 = r0 | 1. */ msr control, r0 /* CONTROL = r0. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vPortAllocateSecureContext: svc 0 /* Secure context is allocated in the supervisor call. portSVC_ALLOCATE_SECURE_CONTEXT = 0. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ /*----------------- Privileged Functions --------------------*/ /*-----------------------------------------------------------*/ SECTION privileged_functions:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ str r4, [r2] /* Disable MPU. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r4, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ movs r4, #4 /* r4 = 4. */ str r4, [r2] /* Program RNR = 4. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldmia r3!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ str r4, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ ldr r5, =xSecureContext str r1, [r5] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ msr control, r3 /* Set this task's CONTROL value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r4 /* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r3 /* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ vRaisePrivilege: mrs r0, control /* Read the CONTROL register. */ bic r0, r0, #1 /* Clear the bit 0. */ msr control, r0 /* Write back the new CONTROL value. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vStartFirstTask: ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ ldr r0, [r0] /* The first entry in vector table is stack pointer. */ msr msp, r0 /* Set the MSP back to the start of the stack. */ cpsie i /* Globally enable interrupts. */ cpsie f dsb isb svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ /*-----------------------------------------------------------*/ ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ /*-----------------------------------------------------------*/ vClearInterruptMask: msr basepri, r0 /* basepri = ulMask. */ dsb isb bx lr /* Return. */ /*-----------------------------------------------------------*/ PendSV_Handler: ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ push {r0-r2, r14} bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r0-r3} /* LR is now in r3. */ mov lr, r3 /* LR = r3. */ lsls r1, r3, #25 /* 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 /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ b select_next_task save_ns_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ adds r2, r2, #16 /* r2 = r2 + 16. */ stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ subs r2, r2, #16 /* r2 = r2 - 16. */ stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ adds r2, r2, #12 /* r2 = r2 + 12. */ stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ subs r2, r2, #12 /* r2 = r2 - 12. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r3] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ str r4, [r3] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ str r4, [r3] /* Program MAIR0. */ ldr r3, =0xe000ed98 /* r3 = 0xe000ed98 [Location of RNR]. */ movs r4, #4 /* r4 = 4. */ str r4, [r3] /* Program RNR = 4. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ stmia r3!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r3] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ str r4, [r3] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ msr control, r3 /* Restore the CONTROL register value for the task. */ mov lr, r4 /* LR = r4. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ push {r2, r4} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r2, r4} mov lr, r4 /* LR = r4. */ lsls r1, r4, #25 /* 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 /* 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 /* Remember the new top of stack for the task. */ bx lr #else /* configENABLE_MPU */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ push {r2, r4} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r2, r4} mov lr, r4 /* LR = r4. */ lsls r1, r4, #25 /* 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 /* 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 /* Remember the new top of stack for the task. */ bx lr #endif /* configENABLE_MPU */ restore_ns_context: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ msr psp, r2 /* Remember the new top of stack for the task. */ bx lr /*-----------------------------------------------------------*/ SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp b vPortSVCHandler_C /*-----------------------------------------------------------*/ vPortFreeSecureContext: /* r0 = uint32_t *pulTCB. */ ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ it ne svcne 1 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 1. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33/non_secure/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M33" #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Be006 #pragma diag_suppress=Pa082 /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACROCOMMON_H #define PORTMACROCOMMON_H #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_FPU #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. #endif /* configENABLE_FPU */ #ifndef configENABLE_MPU #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. #endif /* configENABLE_MPU */ #ifndef configENABLE_TRUSTZONE #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ /** * @brief Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif #define portHAS_STACK_OVERFLOW_CHECKING 1 /*-----------------------------------------------------------*/ /** * @brief Extern declarations. */ extern BaseType_t xPortIsInsideInterrupt( void ); extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; #if ( configENABLE_TRUSTZONE == 1 ) extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_MPU == 1 ) extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief MPU specific constants. */ #if ( configENABLE_MPU == 1 ) #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #else #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* MPU regions. */ #define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_RAM_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ /* Device memory attributes used in MPU_MAIR registers. * * 8-bit values encoded as follows: * Bit[7:4] - 0000 - Device Memory * Bit[3:2] - 00 --> Device-nGnRnE * 01 --> Device-nGnRE * 10 --> Device-nGRE * 11 --> Device-GRE * Bit[1:0] - 00, Reserved. */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ /* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ /* Attributes used in MPU_RBAR registers. */ #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ /** * @brief Settings to define an MPU region. */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */ } MPURegionSettings_t; /** * @brief MPU settings as stored in the TCB. */ typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ } xMPU_SETTINGS; /*-----------------------------------------------------------*/ /** * @brief SVC numbers. */ #define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 /*-----------------------------------------------------------*/ /** * @brief Scheduler utilities. */ #define portYIELD() vPortYield() #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /** * @brief Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /** * @brief Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Allocate a secure context for the task. * * 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 context before it calls any secure function. * * @param[in] ulSecureStackSize The size of the secure stack to be allocated. */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) /** * @brief Called when a task is deleted to delete the task's secure context, * if it has one. * * @param[in] pxTCB The TCB of the task being deleted. */ #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. * * 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, * the privilege is not raised. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() #else #define portIS_PRIVILEGED() #define portRAISE_PRIVILEGE() #define portRESET_PRIVILEGE() #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief Barriers. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACROCOMMON_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33/secure/secure_context.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Secure context includes. */ #include "secure_context.h" /* Secure heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief CONTROL value for privileged tasks. * * Bit[0] - 0 --> Thread mode is privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_PRIVILEGED 0x02 /** * @brief CONTROL value for un-privileged tasks. * * Bit[0] - 1 --> Thread mode is un-privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 /** * @brief Size of stack seal values in bytes. */ #define securecontextSTACK_SEAL_SIZE 8 /** * @brief Stack seal value as recommended by ARM. */ #define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5 /** * @brief Maximum number of secure contexts. */ #ifndef secureconfigMAX_SECURE_CONTEXTS #define secureconfigMAX_SECURE_CONTEXTS 8UL #endif /*-----------------------------------------------------------*/ /** * @brief Pre-allocated array of secure contexts. */ SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ]; /*-----------------------------------------------------------*/ /** * @brief Get a free secure context for a task from the secure context pool (xSecureContexts). * * This function ensures that only one secure context is allocated for a task. * * @param[in] pvTaskHandle The task handle for which the secure context is allocated. * * @return Index of a free secure context in the xSecureContexts array. */ static uint32_t ulGetSecureContext( void * pvTaskHandle ); /** * @brief Return the secure context to the secure context pool (xSecureContexts). * * @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array. */ static void vReturnSecureContext( uint32_t ulSecureContextIndex ); /* These are implemented in assembly. */ extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ); extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ); /*-----------------------------------------------------------*/ static uint32_t ulGetSecureContext( void * pvTaskHandle ) { /* Start with invalid index. */ uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) && ( xSecureContexts[ i ].pucStackLimit == NULL ) && ( xSecureContexts[ i ].pucStackStart == NULL ) && ( xSecureContexts[ i ].pvTaskHandle == NULL ) && ( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = i; } else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle ) { /* A task can only have one secure context. Do not allocate a second * context for the same task. */ ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; break; } } return ulSecureContextIndex; } /*-----------------------------------------------------------*/ static void vReturnSecureContext( uint32_t ulSecureContextIndex ) { xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) { uint32_t ulIPSR, i; static uint32_t ulSecureContextsInitialized = 0; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) ) { /* Ensure to initialize secure contexts only once. */ ulSecureContextsInitialized = 1; /* No stack for thread mode until a task's context is loaded. */ secureportSET_PSPLIM( securecontextNO_STACK ); secureportSET_PSP( securecontextNO_STACK ); /* Initialize all secure contexts. */ for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { xSecureContexts[ i ].pucCurrentStackPointer = NULL; xSecureContexts[ i ].pucStackLimit = NULL; xSecureContexts[ i ].pucStackStart = NULL; xSecureContexts[ i ].pvTaskHandle = NULL; } #if ( configENABLE_MPU == 1 ) { /* Configure thread mode to use PSP and to be unprivileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED ); } #else /* configENABLE_MPU */ { /* Configure thread mode to use PSP and to be privileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED ); } #endif /* configENABLE_MPU */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ) #else /* configENABLE_MPU */ secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ) #endif /* configENABLE_MPU */ { uint8_t * pucStackMemory = NULL; uint8_t * pucStackLimit; uint32_t ulIPSR, ulSecureContextIndex; SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID; #if ( configENABLE_MPU == 1 ) uint32_t * pulCurrentStackPointer = NULL; #endif /* configENABLE_MPU */ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit * Register (PSPLIM) value. */ secureportREAD_IPSR( ulIPSR ); secureportREAD_PSPLIM( pucStackLimit ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. * Also do nothing, if a secure context us already loaded. PSPLIM is set to * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { /* Ontain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space. */ pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE ); if( pucStackMemory != NULL ) { /* Since stack grows down, the starting point will be the last * location. Note that this location is next to the last * allocated byte for stack (excluding the space for seal values) * because the hardware decrements the stack pointer before * writing i.e. if stack pointer is 0x2, a push operation will * decrement the stack pointer to 0x1 and then write at 0x1. */ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize; /* Seal the created secure process stack. */ *( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE; *( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE; /* The stack cannot go beyond this location. This value is * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle; #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 ) { *( 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 /* configENABLE_MPU */ { /* Current SP is set to the starting of the stack. This * value programmed in the PSP register on context switch. */ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart; } #endif /* configENABLE_MPU */ /* Ensure to never return 0 as a valid context handle. */ xSecureContextHandle = ulSecureContextIndex + 1UL; } } } return xSecureContextHandle; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint32_t ulIPSR, ulSecureContextIndex; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* Only free if a valid context handle is passed. */ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; /* Ensure that the secure context being deleted is associated with * the task. */ if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) { /* Free the stack space. */ vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); /* Return the secure context back to the free secure contexts pool. */ vReturnSecureContext( ulSecureContextIndex ); } } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that no secure context is loaded and the task is loading it's * own context. */ if( ( pucStackLimit == securecontextNO_STACK ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that task's context is loaded and the task is saving it's own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33/secure/secure_context.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_CONTEXT_H__ #define __SECURE_CONTEXT_H__ /* Standard includes. */ #include /* FreeRTOS includes. */ #include "FreeRTOSConfig.h" /** * @brief PSP value when no secure context is loaded. */ #define securecontextNO_STACK 0x0 /** * @brief Invalid context ID. */ #define securecontextINVALID_CONTEXT_ID 0UL /*-----------------------------------------------------------*/ /** * @brief Structure to represent a secure context. * * @note Since stack grows down, pucStackStart is the highest address while * pucStackLimit is the first address of the allocated memory. */ typedef struct SecureContext { uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */ uint8_t * pucStackStart; /**< First location of the stack memory. */ void * pvTaskHandle; /**< Task handle of the task this context is associated with. */ } SecureContext_t; /*-----------------------------------------------------------*/ /** * @brief Opaque handle for a secure context. */ typedef uint32_t SecureContextHandle_t; /*-----------------------------------------------------------*/ /** * @brief Initializes the secure context management system. * * PSP is set to NULL and therefore a task must allocate and load a context * before calling any secure side function in the thread mode. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureContext_Init( void ); /** * @brief Allocates a context on the secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] ulSecureStackSize Size of the stack to allocate on secure side. * @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise. * * @return Opaque context handle if context is successfully allocated, NULL * otherwise. */ #if ( configENABLE_MPU == 1 ) SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ); #else /* configENABLE_MPU */ SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ); #endif /* configENABLE_MPU */ /** * @brief Frees the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the * context to be freed. */ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Loads the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be loaded. */ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Saves the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be saved. */ void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); #endif /* __SECURE_CONTEXT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33/secure/secure_context_port_asm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ SECTION .text:CODE:NOROOT(2) THUMB /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" PUBLIC SecureContext_LoadContextAsm PUBLIC SecureContext_SaveContextAsm /*-----------------------------------------------------------*/ SecureContext_LoadContextAsm: /* pxSecureContext value is in r0. */ mrs r1, ipsr /* r1 = IPSR. */ cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ ldmia r0!, {r1, r2} /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */ #if ( configENABLE_MPU == 1 ) ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */ msr control, r3 /* CONTROL = r3. */ #endif /* configENABLE_MPU */ msr psplim, r2 /* PSPLIM = r2. */ msr psp, r1 /* PSP = r1. */ load_ctx_therad_mode: bx lr /*-----------------------------------------------------------*/ SecureContext_SaveContextAsm: /* pxSecureContext value is in r0. */ mrs r1, ipsr /* r1 = IPSR. */ cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ mrs r1, psp /* r1 = PSP. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) vstmdb r1!, {s0} /* Trigger the deferred stacking of FPU registers. */ vldmia r1!, {s0} /* Nullify the effect of the previous statement. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) mrs r2, control /* r2 = CONTROL. */ stmdb r1!, {r2} /* Store CONTROL value on the stack. */ #endif /* configENABLE_MPU */ str r1, [r0] /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ movs r1, #0 /* r1 = securecontextNO_STACK. */ msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */ msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */ save_ctx_therad_mode: bx lr /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33/secure/secure_heap.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure context heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Total heap size. */ #ifndef secureconfigTOTAL_HEAP_SIZE #define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) ) #endif /* No test marker by default. */ #ifndef mtCOVERAGE_TEST_MARKER #define mtCOVERAGE_TEST_MARKER() #endif /* No tracing by default. */ #ifndef traceMALLOC #define traceMALLOC( pvReturn, xWantedSize ) #endif /* No tracing by default. */ #ifndef traceFREE #define traceFREE( pv, xBlockSize ) #endif /* Block sizes must not get too small. */ #define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) /* Assumes 8bit bytes! */ #define secureheapBITS_PER_BYTE ( ( size_t ) 8 ) /*-----------------------------------------------------------*/ /* Allocate the memory for the heap. */ #if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) /* The application writer has already defined the array used for the RTOS * heap - probably so it can be placed in a special segment or address. */ extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #else /* configAPPLICATION_ALLOCATED_HEAP */ static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #endif /* configAPPLICATION_ALLOCATED_HEAP */ /** * @brief The linked list structure. * * This is used to link free blocks in order of their memory address. */ typedef struct A_BLOCK_LINK { struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */ size_t xBlockSize; /**< The size of the free block. */ } BlockLink_t; /*-----------------------------------------------------------*/ /** * @brief Called automatically to setup the required heap structures the first * time pvPortMalloc() is called. */ static void prvHeapInit( void ); /** * @brief Inserts a block of memory that is being freed into the correct * position in the list of free memory blocks. * * The block being freed will be merged with the block in front it and/or the * block behind it if the memory blocks are adjacent to each other. * * @param[in] pxBlockToInsert The block being freed. */ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ); /*-----------------------------------------------------------*/ /** * @brief The size of the structure placed at the beginning of each allocated * memory block must by correctly byte aligned. */ static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); /** * @brief Create a couple of list links to mark the start and end of the list. */ static BlockLink_t xStart; static BlockLink_t * pxEnd = NULL; /** * @brief Keeps track of the number of free bytes remaining, but says nothing * about fragmentation. */ static size_t xFreeBytesRemaining = 0U; static size_t xMinimumEverFreeBytesRemaining = 0U; /** * @brief Gets set to the top bit of an size_t type. * * When this bit in the xBlockSize member of an BlockLink_t structure is set * then the block belongs to the application. When the bit is free the block is * still part of the free heap space. */ static size_t xBlockAllocatedBit = 0; /*-----------------------------------------------------------*/ static void prvHeapInit( void ) { BlockLink_t * pxFirstFreeBlock; uint8_t * pucAlignedHeap; size_t uxAddress; size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE; /* Ensure the heap starts on a correctly aligned boundary. */ uxAddress = ( size_t ) ucHeap; if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 ) { uxAddress += ( secureportBYTE_ALIGNMENT - 1 ); uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; } pucAlignedHeap = ( uint8_t * ) uxAddress; /* xStart is used to hold a pointer to the first item in the list of free * blocks. The void cast is used to prevent compiler warnings. */ xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; xStart.xBlockSize = ( size_t ) 0; /* pxEnd is used to mark the end of the list of free blocks and is inserted * at the end of the heap space. */ uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; uxAddress -= xHeapStructSize; uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); pxEnd = ( void * ) uxAddress; pxEnd->xBlockSize = 0; pxEnd->pxNextFreeBlock = NULL; /* To start with there is a single free block that is sized to take up the * entire heap space, minus the space taken by pxEnd. */ pxFirstFreeBlock = ( void * ) pucAlignedHeap; pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; pxFirstFreeBlock->pxNextFreeBlock = pxEnd; /* Only one block exists - and it covers the entire usable heap space. */ xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; /* Work out the position of the top bit in a size_t variable. */ xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 ); } /*-----------------------------------------------------------*/ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) { BlockLink_t * pxIterator; uint8_t * puc; /* Iterate through the list until a block is found that has a higher address * than the block being inserted. */ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) { /* Nothing to do here, just iterate to the right position. */ } /* Do the block being inserted, and the block it is being inserted after * make a contiguous block of memory? */ puc = ( uint8_t * ) pxIterator; if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) { pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; pxBlockToInsert = pxIterator; } else { mtCOVERAGE_TEST_MARKER(); } /* Do the block being inserted, and the block it is being inserted before * make a contiguous block of memory? */ puc = ( uint8_t * ) pxBlockToInsert; if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) { if( pxIterator->pxNextFreeBlock != pxEnd ) { /* Form one big block from the two blocks. */ pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; } else { pxBlockToInsert->pxNextFreeBlock = pxEnd; } } else { pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } /* If the block being inserted plugged a gab, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ if( pxIterator != pxBlockToInsert ) { pxIterator->pxNextFreeBlock = pxBlockToInsert; } else { mtCOVERAGE_TEST_MARKER(); } } /*-----------------------------------------------------------*/ void * pvPortMalloc( size_t xWantedSize ) { BlockLink_t * pxBlock; BlockLink_t * pxPreviousBlock; BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ if( pxEnd == NULL ) { prvHeapInit(); } else { mtCOVERAGE_TEST_MARKER(); } /* Check the requested block size is not so large that the top bit is set. * The top bit of the block size member of the BlockLink_t structure is used * to determine who owns the block - the application or the kernel, so it * must be free. */ if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) { /* The wanted size is increased so it can contain a BlockLink_t * structure in addition to the requested amount of bytes. */ if( xWantedSize > 0 ) { xWantedSize += xHeapStructSize; /* Ensure that blocks are always aligned to the required number of * bytes. */ if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 ) { /* Byte alignment required. */ xWantedSize += ( secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) ); secureportASSERT( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) == 0 ); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) { /* Traverse the list from the start (lowest address) block until * one of adequate size is found. */ pxPreviousBlock = &xStart; pxBlock = xStart.pxNextFreeBlock; while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) { pxPreviousBlock = pxBlock; pxBlock = pxBlock->pxNextFreeBlock; } /* If the end marker was reached then a block of adequate size was * not found. */ if( pxBlock != pxEnd ) { /* Return the memory space pointed to - jumping over the * BlockLink_t structure at its start. */ pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); /* This block is being returned for use so must be taken out * of the list of free blocks. */ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; /* If the block is larger than required it can be split into * two. */ if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE ) { /* This block is to be split into two. Create a new * block following the number of bytes requested. The void * cast is used to prevent byte alignment warnings from the * compiler. */ pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 ); /* Calculate the sizes of two blocks split from the single * block. */ pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; pxBlock->xBlockSize = xWantedSize; /* Insert the new block into the list of free blocks. */ prvInsertBlockIntoFreeList( pxNewBlockLink ); } else { mtCOVERAGE_TEST_MARKER(); } xFreeBytesRemaining -= pxBlock->xBlockSize; if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) { xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; } else { mtCOVERAGE_TEST_MARKER(); } /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ pxBlock->xBlockSize |= xBlockAllocatedBit; pxBlock->pxNextFreeBlock = NULL; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } traceMALLOC( pvReturn, xWantedSize ); #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { extern void vApplicationMallocFailedHook( void ); vApplicationMallocFailedHook(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */ secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 ); return pvReturn; } /*-----------------------------------------------------------*/ void vPortFree( void * pv ) { uint8_t * puc = ( uint8_t * ) pv; BlockLink_t * pxLink; if( pv != NULL ) { /* The memory being freed will have an BlockLink_t structure immediately * before it. */ puc -= xHeapStructSize; /* This casting is to keep the compiler from issuing warnings. */ pxLink = ( void * ) puc; /* Check the block is actually allocated. */ secureportASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); secureportASSERT( pxLink->pxNextFreeBlock == NULL ); if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) { if( pxLink->pxNextFreeBlock == NULL ) { /* The block is being returned to the heap - it is no longer * allocated. */ pxLink->xBlockSize &= ~xBlockAllocatedBit; secureportDISABLE_NON_SECURE_INTERRUPTS(); { /* Add this block to the list of free blocks. */ xFreeBytesRemaining += pxLink->xBlockSize; traceFREE( pv, pxLink->xBlockSize ); prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); } secureportENABLE_NON_SECURE_INTERRUPTS(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } } /*-----------------------------------------------------------*/ size_t xPortGetFreeHeapSize( void ) { return xFreeBytesRemaining; } /*-----------------------------------------------------------*/ size_t xPortGetMinimumEverFreeHeapSize( void ) { return xMinimumEverFreeBytesRemaining; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33/secure/secure_heap.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_HEAP_H__ #define __SECURE_HEAP_H__ /* Standard includes. */ #include /** * @brief Allocates memory from heap. * * @param[in] xWantedSize The size of the memory to be allocated. * * @return Pointer to the memory region if the allocation is successful, NULL * otherwise. */ void * pvPortMalloc( size_t xWantedSize ); /** * @brief Frees the previously allocated memory. * * @param[in] pv Pointer to the memory to be freed. */ void vPortFree( void * pv ); /** * @brief Get the free heap size. * * @return Free heap size. */ size_t xPortGetFreeHeapSize( void ); /** * @brief Get the minimum ever free heap size. * * @return Minimum ever free heap size. */ size_t xPortGetMinimumEverFreeHeapSize( void ); #endif /* __SECURE_HEAP_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33/secure/secure_init.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure init includes. */ #include "secure_init.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Constants required to manipulate the SCB. */ #define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */ #define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL ) #define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS ) #define secureinitSCB_AIRCR_PRIS_POS ( 14UL ) #define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS ) /** * @brief Constants required to manipulate the FPU. */ #define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define secureinitFPCCR_LSPENS_POS ( 29UL ) #define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS ) #define secureinitFPCCR_TS_POS ( 26UL ) #define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS ) #define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */ #define secureinitNSACR_CP10_POS ( 10UL ) #define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS ) #define secureinitNSACR_CP11_POS ( 11UL ) #define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS ) /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { *( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) | ( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) | ( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK ); } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* CP10 = 1 ==> Non-secure access to the Floating Point Unit is * permitted. CP11 should be programmed to the same value as CP10. */ *( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK ); /* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures * that we can enable/disable lazy stacking in port.c file. */ *( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK ); /* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP * registers (S16-S31) are also pushed to stack on exception entry and * restored on exception return. */ *( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK ); } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33/secure/secure_init.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_INIT_H__ #define __SECURE_INIT_H__ /** * @brief De-prioritizes the non-secure exceptions. * * This is needed to ensure that the non-secure PendSV runs at the lowest * priority. Context switch is done in the non-secure PendSV handler. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_DePrioritizeNSExceptions( void ); /** * @brief Sets up the Floating Point Unit (FPU) for Non-Secure access. * * Also sets FPCCR.TS=1 to ensure that the content of the Floating Point * Registers are not leaked to the non-secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_EnableNSFPUAccess( void ); #endif /* __SECURE_INIT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33/secure/secure_port_macros.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_PORT_MACROS_H__ #define __SECURE_PORT_MACROS_H__ /** * @brief Byte alignment requirements. */ #define secureportBYTE_ALIGNMENT 8 #define secureportBYTE_ALIGNMENT_MASK ( 0x0007 ) /** * @brief Macro to declare a function as non-secure callable. */ #if defined( __IAR_SYSTEMS_ICC__ ) #define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root #else #define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) ) #endif /** * @brief Set the secure PRIMASK value. */ #define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Set the non-secure PRIMASK value. */ #define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Read the PSP value in the given variable. */ #define secureportREAD_PSP( pucOutCurrentStackPointer ) \ __asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) ) /** * @brief Set the PSP to the given value. */ #define secureportSET_PSP( pucCurrentStackPointer ) \ __asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) ) /** * @brief Read the PSPLIM value in the given variable. */ #define secureportREAD_PSPLIM( pucOutStackLimit ) \ __asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) ) /** * @brief Set the PSPLIM to the given value. */ #define secureportSET_PSPLIM( pucStackLimit ) \ __asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) ) /** * @brief Set the NonSecure MSP to the given value. */ #define secureportSET_MSP_NS( pucMainStackPointer ) \ __asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) ) /** * @brief Set the CONTROL register to the given value. */ #define secureportSET_CONTROL( ulControl ) \ __asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" ) /** * @brief Read the Interrupt Program Status Register (IPSR) value in the given * variable. */ #define secureportREAD_IPSR( ulIPSR ) \ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) ) /** * @brief PRIMASK value to enable interrupts. */ #define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0 /** * @brief PRIMASK value to disable interrupts. */ #define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1 /** * @brief Disable secure interrupts. */ #define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Disable non-secure interrupts. * * This effectively disables context switches. */ #define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Enable non-secure interrupts. */ #define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL ) /** * @brief Assert definition. */ #define secureportASSERT( x ) \ if( ( x ) == 0 ) \ { \ secureportDISABLE_SECURE_INTERRUPTS(); \ secureportDISABLE_NON_SECURE_INTERRUPTS(); \ for( ; ; ) {; } \ } #endif /* __SECURE_PORT_MACROS_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33_NTZ/non_secure/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /* Portasm includes. */ #include "portasm.h" #if ( configENABLE_TRUSTZONE == 1 ) /* Secure components includes. */ #include "secure_context.h" #include "secure_init.h" #endif /* configENABLE_TRUSTZONE */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /** * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS * on the secure side. The following are the valid configuration seetings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 * * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 * * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 */ #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. #endif /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the SCB. */ #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the FPU. */ #define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) #define portMPU_RLAR_REGION_ENABLE ( 1UL ) /* Enable privileged access to unmapped region. */ #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /*-----------------------------------------------------------*/ /** * @brief The maximum 24-bit number. * * It is needed because the systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /** * @brief A fiddle factor to estimate the number of SysTick counts that would * have occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) /** * @brief Initial EXC_RETURN value. * * FF FF FF FD * 1111 1111 1111 1111 1111 1111 1111 1101 * * Bit[6] - 1 --> The exception was taken from the Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 1 --> The exception was taken to the Secure state. */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else /** * @brief Initial EXC_RETURN value. * * FF FF FF BC * 1111 1111 1111 1111 1111 1111 1011 1100 * * Bit[6] - 0 --> The exception was taken from the Non-Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 0 --> The exception was taken to the Non-Secure state. */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ /** * @brief CONTROL register privileged bit mask. * * Bit[0] in CONTROL register tells the privilege: * Bit[0] = 0 ==> The task is privileged. * Bit[0] = 1 ==> The task is not privileged. */ #define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) /** * @brief Initial CONTROL register values. */ #define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) #define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) /** * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /** * @brief 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /** * @brief If portPRELOAD_REGISTERS then registers will be given an initial value * when a task is created. This helps in debugging at the cost of code size. */ #define portPRELOAD_REGISTERS 1 /** * @brief A task is created without a secure context, and must call * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes * any secure calls. */ #define portNO_SECURE_CONTEXT 0 /*-----------------------------------------------------------*/ /** * @brief Used to catch tasks that attempt to return from their implementing * function. */ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) /** * @brief Setup the Memory Protection Unit (MPU). */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) /** * @brief Setup the Floating Point Unit (FPU). */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ /** * @brief Setup the timer to generate the tick interrupts. * * The implementation in this file is weak to allow application writers to * change the timer used to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /** * @brief Checks whether the current execution context is interrupt. * * @return pdTRUE if the current execution context is interrupt, pdFALSE * otherwise. */ BaseType_t xPortIsInsideInterrupt( void ); /** * @brief Yield the processor. */ void vPortYield( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ void vPortExitCritical( void ) PRIVILEGED_FUNCTION; /** * @brief SysTick handler. */ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; /** * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. */ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Saved as part of the task context to indicate which context the * task is using on the secure side. */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ #if ( configUSE_TICKLESS_IDLE == 1 ) /** * @brief The number of SysTick increments that make up one tick period. */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; /** * @brief The maximum number of tick periods that can be suppressed is * limited by the 24 bit resolution of the SysTick timer. */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; /** * @brief Compensate for the CPU cycles that pass while the SysTick is * stopped (low power functionality only). */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). Artificially force an assert() * to be triggered if configASSERT() is defined, then stop here so * application writers can catch the error. */ configASSERT( ulCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being * defined but never called. ulDummy is used purely to quieten other * warnings about code appearing after this function is called - making * ulDummy volatile makes the compiler think the function could return * and therefore not output an 'unreachable code' warning for code that * appears after it. */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; extern uint32_t * __unprivileged_flash_start__; extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* if defined( __ARMCC_VERSION ) */ /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; extern uint32_t __unprivileged_flash_start__[]; extern uint32_t __unprivileged_flash_end__[]; extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check that the MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* MAIR0 - Index 0. */ portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); /* MAIR0 - Index 1. */ portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* Setup privileged flash as Read Only so that privileged tasks can * read it but not modify. */ portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged flash as Read Only by both privileged and * unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged syscalls flash as Read Only by both privileged * and unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup RAM containing kernel data for privileged access only. */ portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Enable mem fault. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; /* Enable MPU with privileged background access i.e. unmapped * regions have privileged access. */ portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) { /* Enable non-secure access to the FPU. */ SecureInit_EnableNSFPUAccess(); } #endif /* configENABLE_TRUSTZONE */ /* CP10 = 11 ==> Full access to FPU i.e. both privileged and * unprivileged code should be able to access FPU. CP11 should be * programmed to the same value as CP10. */ *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) ); /* ASPEN = 1 ==> Hardware should automatically preserve floating point * context on exception entry and restore on exception return. * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ void vPortYield( void ) /* PRIVILEGED_FUNCTION */ { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ { portDISABLE_INTERRUPTS(); ulCriticalNesting++; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ { configASSERT( ulCriticalNesting ); ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { #if ( configENABLE_MPU == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ #endif /* configENABLE_MPU */ uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) uint32_t ulR0, ulR1; extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ #endif /* configENABLE_TRUSTZONE */ uint8_t ucSVCNumber; /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ ulPC = pulCallerStackAddress[ 6 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { #if ( configENABLE_TRUSTZONE == 1 ) case portSVC_ALLOCATE_SECURE_CONTEXT: /* R0 contains the stack size passed as parameter to the * vPortAllocateSecureContext function. */ ulR0 = pulCallerStackAddress[ 0 ]; #if ( configENABLE_MPU == 1 ) { /* Read the CONTROL register value. */ __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); /* The task that raised the SVC is privileged if Bit[0] * in the CONTROL register is 0. */ ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: /* R0 contains TCB being freed and R1 contains the secure * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) { /* De-prioritize the non-secure exceptions so that the * non-secure pendSV runs at the lowest priority. */ SecureInit_DePrioritizeNSExceptions(); /* Initialize the secure context management system. */ SecureContext_Init(); } #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_FPU == 1 ) { /* Setup the Floating Point Unit (FPU). */ prvSetupFPU(); } #endif /* configENABLE_FPU */ /* Setup the context of the first task so that the first task starts * executing. */ vRestoreContextOfFirstTask(); break; #if ( configENABLE_MPU == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the svc was raised from any of * the system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { vRaisePrivilege(); } break; #endif /* configENABLE_MPU */ default: /* Incorrect SVC call. */ configASSERT( pdFALSE ); } } /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #if ( configENABLE_MPU == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /* *INDENT-ON* */ { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #endif /* portPRELOAD_REGISTERS */ return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ prvSetupMPU(); } #endif /* configENABLE_MPU */ /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; /* Start the first task. */ vStartFirstTask(); /* Should never get here as the tasks will now be executing. Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* Setup MAIR0. */ xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ if( ulStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged * SRAM is already protected using an MPU region and ARMv8-M does * not allow overlapping MPU regions. */ if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) { xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; } else { /* Define the region that allows access to the stack. */ ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); } } /* User supplied configurable regions. */ for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) { /* If xRegions is NULL i.e. the task has not specified any MPU * region, the else part ensures that all the configurable MPU * regions are invalidated. */ if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) { /* Translate the generic region definition contained in xRegions * into the ARMv8 specific MPU settings that are then stored in * xMPUSettings. */ ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; /* Start address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ); /* RO/RW. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); } else { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); } /* XN. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); } /* End Address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { /* Attr1 in MAIR0 is configured as device memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; } else { /* Attr0 in MAIR0 is configured as normal memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; } } else { /* Invalidate the region. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; } lIndex++; } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. Interrupt Program * Status Register (IPSR) holds the exception number of the currently-executing * exception or zero for Thread mode.*/ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORT_ASM_H__ #define __PORT_ASM_H__ /* Scheduler includes. */ #include "FreeRTOS.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /** * @brief Restore the context of the first task so that the first task starts * executing. */ void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * * @note This is a privileged function and should only be called from the kenrel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Starts the first task. */ void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Disables interrupts. */ uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Enables interrupts. */ void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief PendSV Exception handler. */ void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief SVC Handler. */ void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Allocate a Secure context for the calling task. * * @param[in] ulSecureStackSize The size of the stack to be allocated on the * secure side for the calling task. */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); /** * @brief Free the task's secure context. * * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. */ void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* __PORT_ASM_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" EXTERN pxCurrentTCB EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C PUBLIC xIsPrivileged PUBLIC vResetPrivilege PUBLIC vRestoreContextOfFirstTask PUBLIC vRaisePrivilege PUBLIC vStartFirstTask PUBLIC ulSetInterruptMask PUBLIC vClearInterruptMask PUBLIC PendSV_Handler PUBLIC SVC_Handler /*-----------------------------------------------------------*/ /*---------------- Unprivileged Functions -------------------*/ /*-----------------------------------------------------------*/ SECTION .text:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ xIsPrivileged: mrs r0, control /* r0 = CONTROL. */ tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ ite ne movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ vResetPrivilege: mrs r0, control /* r0 = CONTROL. */ orr r0, r0, #1 /* r0 = r0 | 1. */ msr control, r0 /* CONTROL = r0. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ /*----------------- Privileged Functions --------------------*/ /*-----------------------------------------------------------*/ SECTION privileged_functions:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ str r4, [r2] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r3, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ movs r3, #4 /* r3 = 4. */ str r3, [r2] /* Program RNR = 4. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ str r4, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ msr control, r2 /* Set this task's CONTROL value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r3 /* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r2 /* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ vRaisePrivilege: mrs r0, control /* Read the CONTROL register. */ bic r0, r0, #1 /* Clear the bit 0. */ msr control, r0 /* Write back the new CONTROL value. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vStartFirstTask: ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ ldr r0, [r0] /* The first entry in vector table is stack pointer. */ msr msp, r0 /* Set the MSP back to the start of the stack. */ cpsie i /* Globally enable interrupts. */ cpsie f dsb isb svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ /*-----------------------------------------------------------*/ ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ /*-----------------------------------------------------------*/ vClearInterruptMask: msr basepri, r0 /* basepri = ulMask. */ dsb isb bx lr /* Return. */ /*-----------------------------------------------------------*/ PendSV_Handler: mrs r0, psp /* Read PSP in r0. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r0!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) mrs r1, psplim /* r1 = PSPLIM. */ mrs r2, control /* r2 = CONTROL. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r1-r11} /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ #else /* configENABLE_MPU */ mrs r2, psplim /* r2 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ #endif /* configENABLE_MPU */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ str r4, [r2] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r3, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ movs r3, #4 /* r3 = 4. */ str r3, [r2] /* Program RNR = 4. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ str r4, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldmia r0!, {r1-r11} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ #else /* configENABLE_MPU */ ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #endif /* configENABLE_MPU */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst r3, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r0!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) msr psplim, r1 /* Restore the PSPLIM register value for the task. */ msr control, r2 /* Restore the CONTROL register value for the task. */ #else /* configENABLE_MPU */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */ #endif /* configENABLE_MPU */ msr psp, r0 /* Remember the new top of stack for the task. */ bx r3 /*-----------------------------------------------------------*/ SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp b vPortSVCHandler_C /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33_NTZ/non_secure/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M33" #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Be006 #pragma diag_suppress=Pa082 /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACROCOMMON_H #define PORTMACROCOMMON_H #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_FPU #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. #endif /* configENABLE_FPU */ #ifndef configENABLE_MPU #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. #endif /* configENABLE_MPU */ #ifndef configENABLE_TRUSTZONE #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ /** * @brief Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif #define portHAS_STACK_OVERFLOW_CHECKING 1 /*-----------------------------------------------------------*/ /** * @brief Extern declarations. */ extern BaseType_t xPortIsInsideInterrupt( void ); extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; #if ( configENABLE_TRUSTZONE == 1 ) extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_MPU == 1 ) extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief MPU specific constants. */ #if ( configENABLE_MPU == 1 ) #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #else #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* MPU regions. */ #define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_RAM_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ /* Device memory attributes used in MPU_MAIR registers. * * 8-bit values encoded as follows: * Bit[7:4] - 0000 - Device Memory * Bit[3:2] - 00 --> Device-nGnRnE * 01 --> Device-nGnRE * 10 --> Device-nGRE * 11 --> Device-GRE * Bit[1:0] - 00, Reserved. */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ /* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ /* Attributes used in MPU_RBAR registers. */ #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ /** * @brief Settings to define an MPU region. */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */ } MPURegionSettings_t; /** * @brief MPU settings as stored in the TCB. */ typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ } xMPU_SETTINGS; /*-----------------------------------------------------------*/ /** * @brief SVC numbers. */ #define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 /*-----------------------------------------------------------*/ /** * @brief Scheduler utilities. */ #define portYIELD() vPortYield() #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /** * @brief Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /** * @brief Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Allocate a secure context for the task. * * 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 context before it calls any secure function. * * @param[in] ulSecureStackSize The size of the secure stack to be allocated. */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) /** * @brief Called when a task is deleted to delete the task's secure context, * if it has one. * * @param[in] pxTCB The TCB of the task being deleted. */ #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. * * 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, * the privilege is not raised. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() #else #define portIS_PRIVILEGED() #define portRAISE_PRIVILEGE() #define portRESET_PRIVILEGE() #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief Barriers. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACROCOMMON_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM4F/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM4F port. *----------------------------------------------------------*/ /* IAR includes. */ #include /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #ifndef __ARMVFP__ #error This port can only be used when the project options are configured to enable hardware floating point support. #endif #if ( configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 ) #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ #endif /* Constants required to manipulate the core. Registers first... */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) /* ...then bits in the registers. */ #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) /* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7 * r0p1 port. */ #define portCPUID ( *( ( volatile uint32_t * ) 0xE000ed00 ) ) #define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) #define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) #define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) ) #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ #define portVECTACTIVE_MASK ( 0xFFUL ) /* Constants required to manipulate the VFP. */ #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_EXC_RETURN ( 0xfffffffd ) /* The systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /* A fiddle factor to estimate the number of SysTick counts that would have * occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) /* Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ); /* * Exception handlers. */ void xPortSysTickHandler( void ); /* * Start first task is a separate function so it can be tested in isolation. */ extern void vPortStartFirstTask( void ); /* * Turn the VFP on. */ extern void vPortEnableVFP( void ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* Each task maintains its own interrupt status in the critical nesting * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* * The number of SysTick increments that make up one tick period. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulTimerCountsForOneTick = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * The maximum number of tick periods that can be suppressed is limited by the * 24 bit resolution of the SysTick timer. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t xMaximumPossibleSuppressedTicks = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Compensate for the CPU cycles that pass while the SysTick is stopped (low * power functionality only. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. */ #if ( configASSERT_DEFINED == 1 ) static uint8_t ucMaxSysCallPriority = 0; static uint32_t ulMaxPRIGROUPValue = 0; static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ /* Offset added to account for the way the MCU uses the stack on entry/exit * of interrupts, and to ensure alignment. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */ /* Save code space by skipping register initialisation. */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ /* A save method is being used that requires each task to maintain its * own exec return value. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). * * Artificially force an assert() to be triggered if configASSERT() is * defined, then stop here so application writers can catch the error. */ configASSERT( uxCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); for( ; ; ) { } } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); /* This port can be used on all revisions of the Cortex-M7 core other than * the r0p1 parts. r0p1 parts should use the port from the * /source/portable/GCC/ARM_CM7/r0p1 directory. */ configASSERT( portCPUID != portCORTEX_M7_r0p1_ID ); configASSERT( portCPUID != portCORTEX_M7_r0p0_ID ); #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API * functions can be called. ISR safe functions are those that end in * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { ulMaxPRIGROUPValue--; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); } #endif /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; /* Restore the clobbered interrupt priority register to its original * value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Ensure the VFP is enabled - it should be anyway. */ vPortEnableVFP(); /* Lazy save always. */ *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; /* Start the first task. */ vPortStartFirstTask(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); uxCriticalNesting++; /* 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 * 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 * assert function also uses a critical section. */ if( uxCriticalNesting == 1 ) { configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { /* The SysTick runs at the lowest interrupt priority, so when this interrupt * executes all interrupts must be unmasked. There is therefore no need to * save and then restore the interrupt mask value as its value is already * known. */ portDISABLE_INTERRUPTS(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* A context switch is required. Context switching is performed in * the PendSV interrupt. Pend the PendSV interrupt. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portENABLE_INTERRUPTS(); } /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __weak void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __disable_interrupt(); __DSB(); __ISB(); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the __disable_interrupt() * call above. */ __enable_interrupt(); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __DSB(); __WFI(); __ISB(); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the __disable_interrupt() call above. */ __enable_interrupt(); __DSB(); __ISB(); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __disable_interrupt(); __DSB(); __ISB(); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __enable_interrupt(); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ /* * Setup the systick timer to generate the tick interrupts at the required * frequency. */ __weak void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and clear the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); } /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); /* Is the interrupt number a user defined interrupt? */ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /* Look up the interrupt's priority. */ ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Interrupts that use the FreeRTOS API must not be left at their * default priority of zero as that is the highest possible priority, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * and therefore also guaranteed to be invalid. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } /* Priority grouping: The interrupt controller (NVIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined * to be pre-emption priority bits. The following assertion will fail if * this is not the case (if some bits represent a sub-priority). * * If the application only uses CMSIS libraries for interrupt * configuration then the correct setting can be achieved on all Cortex-M * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * scheduler. Note however that some vendor specific peripheral libraries * assume a non-zero priority group setting, in which cases using a value * of zero will result in unpredictable behaviour. */ configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); } #endif /* configASSERT_DEFINED */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM4F/portasm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #include RSEG CODE:CODE(2) thumb EXTERN pxCurrentTCB EXTERN vTaskSwitchContext PUBLIC xPortPendSVHandler PUBLIC vPortSVCHandler PUBLIC vPortStartFirstTask PUBLIC vPortEnableVFP /*-----------------------------------------------------------*/ xPortPendSVHandler: mrs r0, psp isb /* Get the location of the current TCB. */ ldr r3, =pxCurrentTCB ldr r2, [r3] /* Is the task using the FPU context? If so, push high vfp registers. */ tst r14, #0x10 it eq vstmdbeq r0!, {s16-s31} /* Save the core registers. */ stmdb r0!, {r4-r11, r14} /* Save the new top of stack into the first member of the TCB. */ str r0, [r2] stmdb sp!, {r0, r3} mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r0 dsb isb bl vTaskSwitchContext mov r0, #0 msr basepri, r0 ldmia sp!, {r0, r3} /* The first item in pxCurrentTCB is the task top of stack. */ ldr r1, [r3] ldr r0, [r1] /* Pop the core registers. */ ldmia r0!, {r4-r11, r14} /* Is the task using the FPU context? If so, pop the high vfp registers too. */ tst r14, #0x10 it eq vldmiaeq r0!, {s16-s31} msr psp, r0 isb #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */ #if WORKAROUND_PMU_CM001 == 1 push { r14 } pop { pc } #endif #endif bx r14 /*-----------------------------------------------------------*/ vPortSVCHandler: /* Get the location of the current TCB. */ ldr r3, =pxCurrentTCB ldr r1, [r3] ldr r0, [r1] /* Pop the core registers. */ ldmia r0!, {r4-r11, r14} msr psp, r0 isb mov r0, #0 msr basepri, r0 bx r14 /*-----------------------------------------------------------*/ vPortStartFirstTask /* Use the NVIC offset register to locate the stack. */ ldr r0, =0xE000ED08 ldr r0, [r0] ldr r0, [r0] /* Set the msp back to the start of the stack. */ msr msp, r0 /* Clear the bit that indicates the FPU is in use in case the FPU was used before the scheduler was started - which would otherwise result in the unnecessary leaving of space in the SVC stack for lazy saving of FPU registers. */ mov r0, #0 msr control, r0 /* Call SVC to start the first task. */ cpsie i cpsie f dsb isb svc 0 /*-----------------------------------------------------------*/ vPortEnableVFP: /* The FPU enable bits are in the CPACR. */ ldr.w r0, =0xE000ED88 ldr r1, [r0] /* Enable CP10 and CP11 coprocessors, then save back. */ orr r1, r1, #( 0xf << 20 ) str r1, [r0] bx r14 END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM4F/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* IAR includes. */ #include /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Compiler directives. */ #define portWEAK_SYMBOL __attribute__( ( weak ) ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ #define portYIELD() \ { \ /* Set a PendSV to request a context switch. */ \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ __DSB(); \ __ISB(); \ } #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 ) /* Check the configuration. */ #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. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) __CLZ( ( uxReadyPriorities ) ) ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); #define portDISABLE_INTERRUPTS() \ { \ __set_BASEPRI( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \ __DSB(); \ __ISB(); \ } #define portENABLE_INTERRUPTS() __set_BASEPRI( 0 ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() #define portSET_INTERRUPT_MASK_FROM_ISR() __get_BASEPRI(); portDISABLE_INTERRUPTS() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) __set_BASEPRI( x ) /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /* 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 * (which build with all the ports) will build. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* portNOP() is not required by this port. */ #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif /*-----------------------------------------------------------*/ portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Pe191 #pragma diag_suppress=Pa082 #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM4F_MPU/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM4F MPU port. *----------------------------------------------------------*/ /* IAR includes. */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #ifndef __ARMVFP__ #error This port can only be used when the project options are configured to enable hardware floating point support. #endif #if ( configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 ) #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ #endif #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #else /* The way the SysTick is clocked is not modified in case it is not the same * as the core. */ #define portNVIC_SYSTICK_CLK_BIT ( 0 ) #endif #ifndef configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS #warning "configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS is not defined. We recommend defining it to 0 in FreeRTOSConfig.h for better security." #define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1 #endif /* Constants required to manipulate the core. Registers first... */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SHPR2_REG ( *( ( volatile uint32_t * ) 0xe000ed1c ) ) #define portNVIC_SYS_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portNVIC_MEM_FAULT_ENABLE ( 1UL << 16UL ) /* Constants required to access and manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_REGION_BASE_ADDRESS_REG ( *( ( volatile uint32_t * ) 0xe000ed9C ) ) #define portMPU_REGION_ATTRIBUTE_REG ( *( ( volatile uint32_t * ) 0xe000edA0 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) #define portMPU_ENABLE ( 0x01UL ) #define portMPU_BACKGROUND_ENABLE ( 1UL << 2UL ) #define portPRIVILEGED_EXECUTION_START_ADDRESS ( 0UL ) #define portMPU_REGION_VALID ( 0x10UL ) #define portMPU_REGION_ENABLE ( 0x01UL ) #define portPERIPHERALS_START_ADDRESS 0x40000000UL #define portPERIPHERALS_END_ADDRESS 0x5FFFFFFFUL /* ...then bits in the registers. */ #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) /* Constants used to detect Cortex-M7 r0p0 and r0p1 cores, and ensure * that a work around is active for errata 837070. */ #define portCPUID ( *( ( volatile uint32_t * ) 0xE000ed00 ) ) #define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) #define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) #define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) #define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) ) #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ #define portVECTACTIVE_MASK ( 0xFFUL ) /* Constants required to manipulate the VFP. */ #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 ) #define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 ) /* Offsets in the stack to the parameters when inside the SVC handler. */ #define portOFFSET_TO_PC ( 6 ) /* The systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /* A fiddle factor to estimate the number of SysTick counts that would have * occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 45UL ) /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) /* * Configure a number of standard MPU regions that are used by all tasks. */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; /* * Return the smallest MPU region size that a given number of bytes will fit * into. The region size is returned as the value that should be programmed * into the region attribute register for that region. */ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) PRIVILEGED_FUNCTION; /* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ); /* * Exception handlers. */ void xPortSysTickHandler( void ) PRIVILEGED_FUNCTION; /* * Start first task is a separate function so it can be tested in isolation. */ extern void vPortStartFirstTask( void ) PRIVILEGED_FUNCTION; /* * Turn the VFP on. */ extern void vPortEnableVFP( void ); /* * The C portion of the SVC handler. */ void vPortSVCHandler_C( uint32_t * pulParam ); /* * Called from the SVC handler used to start the scheduler. */ extern void vPortRestoreContextOfFirstTask( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ #if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL; #else void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; #endif /** * @brief Exit from critical section. */ #if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL; #else void vPortExitCritical( void ) PRIVILEGED_FUNCTION; #endif /*-----------------------------------------------------------*/ /* Each task maintains its own interrupt status in the critical nesting * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. */ #if ( configASSERT_DEFINED == 1 ) static uint8_t ucMaxSysCallPriority = 0; static uint32_t ulMaxPRIGROUPValue = 0; static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ /* Offset added to account for the way the MCU uses the stack on entry/exit * of interrupts, and to ensure alignment. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0; /* LR */ /* Save code space by skipping register initialisation. */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ /* A save method is being used that requires each task to maintain its * own exec return value. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack -= 9; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_IF_PRIVILEGED; } else { *pxTopOfStack = portINITIAL_CONTROL_IF_UNPRIVILEGED; } return pxTopOfStack; } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulParam ) { uint8_t ucSVCNumber; uint32_t ulPC; #if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ /* The stack contains: r0, r1, r2, r3, r12, LR, PC and xPSR. The first * argument (r0) is pulParam[ 0 ]. */ ulPC = pulParam[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { case portSVC_START_SCHEDULER: portNVIC_SHPR2_REG |= portNVIC_SVC_PRI; vPortRestoreContextOfFirstTask(); break; case portSVC_YIELD: portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required * but do ensure the code is completely * within the specified behaviour for the * architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); break; #if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the * svc was raised from any of the * system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { __asm volatile ( " mrs r1, control \n"/* Obtain current control value. */ " bic r1, r1, #1 \n"/* Set privilege bit. */ " msr control, r1 \n"/* Write back new control value. */ ::: "r1", "memory" ); } break; #else /* if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ case portSVC_RAISE_PRIVILEGE: __asm volatile ( " mrs r1, control \n"/* Obtain current control value. */ " bic r1, r1, #1 \n"/* Set privilege bit. */ " msr control, r1 \n"/* Write back new control value. */ ::: "r1", "memory" ); break; #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ default: /* Unknown SVC call. */ break; } } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); /* Errata 837070 workaround must only be enabled on Cortex-M7 r0p0 * and r0p1 cores. */ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) configASSERT( ( portCPUID == portCORTEX_M7_r0p1_ID ) || ( portCPUID == portCORTEX_M7_r0p0_ID ) ); #else /* When using this port on a Cortex-M7 r0p0 or r0p1 core, define * configENABLE_ERRATA_837070_WORKAROUND to 1 in your * FreeRTOSConfig.h. */ configASSERT( portCPUID != portCORTEX_M7_r0p1_ID ); configASSERT( portCPUID != portCORTEX_M7_r0p0_ID ); #endif #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API * functions can be called. ISR safe functions are those that end in * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { ulMaxPRIGROUPValue--; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); } #endif /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; /* Restore the clobbered interrupt priority register to its original * value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Configure the regions in the MPU that are common to all tasks. */ prvSetupMPU(); /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Ensure the VFP is enabled - it should be anyway. */ vPortEnableVFP(); /* Lazy save always. */ *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; /* Start the first task. */ vPortStartFirstTask(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { #if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); portDISABLE_INTERRUPTS(); uxCriticalNesting++; /* 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 * 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 * assert function also uses a critical section. */ if( uxCriticalNesting == 1 ) { configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); } portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { portDISABLE_INTERRUPTS(); uxCriticalNesting++; /* 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 * 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 * assert function also uses a critical section. */ if( uxCriticalNesting == 1 ) { configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); } } #else portDISABLE_INTERRUPTS(); uxCriticalNesting++; /* 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 * 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 * assert function also uses a critical section. */ if( uxCriticalNesting == 1 ) { configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); } #endif } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { #if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } #else configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } #endif } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { /* The SysTick runs at the lowest interrupt priority, so when this interrupt * executes all interrupts must be unmasked. There is therefore no need to * save and then restore the interrupt mask value as its value is already * known. */ portDISABLE_INTERRUPTS(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* A context switch is required. Context switching is performed in * the PendSV interrupt. Pend the PendSV interrupt. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portENABLE_INTERRUPTS(); } /*-----------------------------------------------------------*/ /* * Setup the systick timer to generate the tick interrupts at the required * frequency. */ __weak void vPortSetupTimerInterrupt( void ) { /* Stop and clear the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); } /*-----------------------------------------------------------*/ static void prvSetupMPU( void ) { extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __FLASH_segment_start__[]; extern uint32_t __FLASH_segment_end__[]; extern uint32_t __privileged_data_start__[]; extern uint32_t __privileged_data_end__[]; /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check the expected MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* First setup the unprivileged flash for unprivileged read only access. */ portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __FLASH_segment_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | ( portUNPRIVILEGED_FLASH_REGION ); portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_READ_ONLY ) | ( ( configTEX_S_C_B_FLASH & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( prvGetMPURegionSizeSetting( ( uint32_t ) __FLASH_segment_end__ - ( uint32_t ) __FLASH_segment_start__ ) ) | ( portMPU_REGION_ENABLE ); /* Setup the privileged flash for privileged only access. This is where * the kernel code is placed. */ portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_functions_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | ( portPRIVILEGED_FLASH_REGION ); portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_PRIVILEGED_READ_ONLY ) | ( ( configTEX_S_C_B_FLASH & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_functions_end__ - ( uint32_t ) __privileged_functions_start__ ) ) | ( portMPU_REGION_ENABLE ); /* Setup the privileged data RAM region. This is where the kernel data * is placed. */ portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | ( portPRIVILEGED_RAM_REGION ); portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ) | ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_data_end__ - ( uint32_t ) __privileged_data_start__ ) | ( portMPU_REGION_ENABLE ); /* By default allow everything to access the general peripherals. The * system peripherals and registers are protected. */ portMPU_REGION_BASE_ADDRESS_REG = ( portPERIPHERALS_START_ADDRESS ) | ( portMPU_REGION_VALID ) | ( portGENERAL_PERIPHERALS_REGION ); portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_READ_WRITE | portMPU_REGION_EXECUTE_NEVER ) | ( prvGetMPURegionSizeSetting( portPERIPHERALS_END_ADDRESS - portPERIPHERALS_START_ADDRESS ) ) | ( portMPU_REGION_ENABLE ); /* Enable the memory fault exception. */ portNVIC_SYS_CTRL_STATE_REG |= portNVIC_MEM_FAULT_ENABLE; /* Enable the MPU with the background region configured. */ portMPU_CTRL_REG |= ( portMPU_ENABLE | portMPU_BACKGROUND_ENABLE ); } } /*-----------------------------------------------------------*/ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) { uint32_t ulRegionSize, ulReturnValue = 4; /* 32 is the smallest region size, 31 is the largest valid value for * ulReturnValue. */ for( ulRegionSize = 32UL; ulReturnValue < 31UL; ( ulRegionSize <<= 1UL ) ) { if( ulActualSizeInBytes <= ulRegionSize ) { break; } else { ulReturnValue++; } } /* Shift the code by one before returning so it can be written directly * into the the correct bit position of the attribute register. */ return( ulReturnValue << 1UL ); } /*-----------------------------------------------------------*/ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { extern uint32_t __SRAM_segment_start__[]; extern uint32_t __SRAM_segment_end__[]; extern uint32_t __privileged_data_start__[]; extern uint32_t __privileged_data_end__[]; int32_t lIndex; uint32_t ul; if( xRegions == NULL ) { /* No MPU regions are specified so allow access to all RAM. */ xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = ( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | ( portSTACK_REGION ); /* Region number. */ xMPUSettings->xRegion[ 0 ].ulRegionAttribute = ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ) | ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( prvGetMPURegionSizeSetting( ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__ ) ) | ( portMPU_REGION_ENABLE ); /* Invalidate user configurable regions. */ for( ul = 1UL; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) { xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID ); xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; } } else { /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that the * stack region has already been configured. */ if( ulStackDepth > 0 ) { /* Define the region that allows access to the stack. */ xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = ( ( uint32_t ) pxBottomOfStack ) | ( portMPU_REGION_VALID ) | ( portSTACK_REGION ); /* Region number. */ xMPUSettings->xRegion[ 0 ].ulRegionAttribute = ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ) | ( prvGetMPURegionSizeSetting( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) ) | ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( portMPU_REGION_ENABLE ); } lIndex = 0; for( ul = 1UL; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) { if( ( xRegions[ lIndex ] ).ulLengthInBytes > 0UL ) { /* Translate the generic region definition contained in * xRegions into the CM4 specific MPU settings that are then * stored in xMPUSettings. */ xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) | ( portMPU_REGION_VALID ) | ( ul - 1UL ); /* Region number. */ xMPUSettings->xRegion[ ul ].ulRegionAttribute = ( prvGetMPURegionSizeSetting( xRegions[ lIndex ].ulLengthInBytes ) ) | ( xRegions[ lIndex ].ulParameters ) | ( portMPU_REGION_ENABLE ); } else { /* Invalidate the region. */ xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID ); xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; } lIndex++; } } } /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); /* Is the interrupt number a user defined interrupt? */ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /* Look up the interrupt's priority. */ ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Interrupts that use the FreeRTOS API must not be left at their * default priority of zero as that is the highest possible priority, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * and therefore also guaranteed to be invalid. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } /* Priority grouping: The interrupt controller (NVIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined * to be pre-emption priority bits. The following assertion will fail if * this is not the case (if some bits represent a sub-priority). * * If the application only uses CMSIS libraries for interrupt * configuration then the correct setting can be achieved on all Cortex-M * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * scheduler. Note however that some vendor specific peripheral libraries * assume a non-zero priority group setting, in which cases using a value * of zero will result in unpredictable behaviour. */ configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); } #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM4F_MPU/portasm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include RSEG CODE:CODE(2) thumb EXTERN pxCurrentTCB EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C PUBLIC xPortPendSVHandler PUBLIC vPortSVCHandler PUBLIC vPortStartFirstTask PUBLIC vPortEnableVFP PUBLIC vPortRestoreContextOfFirstTask PUBLIC xIsPrivileged PUBLIC vResetPrivilege /*-----------------------------------------------------------*/ xPortPendSVHandler: mrs r0, psp isb /* Get the location of the current TCB. */ ldr r3, =pxCurrentTCB ldr r2, [r3] /* Is the task using the FPU context? If so, push high vfp registers. */ tst r14, #0x10 it eq vstmdbeq r0!, {s16-s31} /* Save the core registers. */ mrs r1, control stmdb r0!, {r1, r4-r11, r14} /* Save the new top of stack into the first member of the TCB. */ str r0, [r2] stmdb sp!, {r0, r3} mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) cpsid i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ #endif msr basepri, r0 dsb isb #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) cpsie i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ #endif bl vTaskSwitchContext mov r0, #0 msr basepri, r0 ldmia sp!, {r0, r3} /* The first item in pxCurrentTCB is the task top of stack. */ ldr r1, [r3] ldr r0, [r1] /* Move onto the second item in the TCB... */ add r1, r1, #4 dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* MPU_CTRL register. */ ldr r3, [r2] /* Read the value of MPU_CTRL. */ bic r3, r3, #1 /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ str r3, [r2] /* Disable MPU. */ /* Region Base Address register. */ ldr r2, =0xe000ed9c /* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */ ldmia r1!, {r4-r11} /* Write 4 sets of MPU registers [MPU Region # 4 - 7]. */ stmia r2, {r4-r11} #ifdef configTOTAL_MPU_REGIONS #if ( configTOTAL_MPU_REGIONS == 16 ) /* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */ ldmia r1!, {r4-r11} /* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */ stmia r2, {r4-r11} /* Read 4 sets of MPU registers [MPU Region # 12 - 15]. */ ldmia r1!, {r4-r11} /* Write 4 sets of MPU registers. [MPU Region # 12 - 15]. */ stmia r2, {r4-r11} #endif /* configTOTAL_MPU_REGIONS == 16. */ #endif /* configTOTAL_MPU_REGIONS */ ldr r2, =0xe000ed94 /* MPU_CTRL register. */ ldr r3, [r2] /* Read the value of MPU_CTRL. */ orr r3, r3, #1 /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ str r3, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ /* Pop the registers that are not automatically saved on exception entry. */ ldmia r0!, {r3-r11, r14} msr control, r3 /* Is the task using the FPU context? If so, pop the high vfp registers too. */ tst r14, #0x10 it eq vldmiaeq r0!, {s16-s31} msr psp, r0 isb bx r14 /*-----------------------------------------------------------*/ vPortSVCHandler: #ifndef USE_PROCESS_STACK /* Code should not be required if a main() is using the process stack. */ tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp #else mrs r0, psp #endif b vPortSVCHandler_C /*-----------------------------------------------------------*/ vPortStartFirstTask: /* Use the NVIC offset register to locate the stack. */ ldr r0, =0xE000ED08 ldr r0, [r0] ldr r0, [r0] /* Set the msp back to the start of the stack. */ msr msp, r0 /* Clear the bit that indicates the FPU is in use in case the FPU was used before the scheduler was started - which would otherwise result in the unnecessary leaving of space in the SVC stack for lazy saving of FPU registers. */ mov r0, #0 msr control, r0 /* Call SVC to start the first task. */ cpsie i cpsie f dsb isb svc 0 /*-----------------------------------------------------------*/ vPortRestoreContextOfFirstTask: /* Use the NVIC offset register to locate the stack. */ ldr r0, =0xE000ED08 ldr r0, [r0] ldr r0, [r0] /* Set the msp back to the start of the stack. */ msr msp, r0 /* Restore the context. */ ldr r3, =pxCurrentTCB ldr r1, [r3] /* The first item in the TCB is the task top of stack. */ ldr r0, [r1] /* Move onto the second item in the TCB... */ add r1, r1, #4 dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* MPU_CTRL register. */ ldr r3, [r2] /* Read the value of MPU_CTRL. */ bic r3, r3, #1 /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ str r3, [r2] /* Disable MPU. */ /* Region Base Address register. */ ldr r2, =0xe000ed9c /* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */ ldmia r1!, {r4-r11} /* Write 4 sets of MPU registers [MPU Region # 4 - 7]. */ stmia r2, {r4-r11} #ifdef configTOTAL_MPU_REGIONS #if ( configTOTAL_MPU_REGIONS == 16 ) /* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */ ldmia r1!, {r4-r11} /* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */ stmia r2, {r4-r11} /* Read 4 sets of MPU registers [MPU Region # 12 - 15]. */ ldmia r1!, {r4-r11} /* Write 4 sets of MPU registers. [MPU Region # 12 - 15]. */ stmia r2, {r4-r11} #endif /* configTOTAL_MPU_REGIONS == 16. */ #endif /* configTOTAL_MPU_REGIONS */ ldr r2, =0xe000ed94 /* MPU_CTRL register. */ ldr r3, [r2] /* Read the value of MPU_CTRL. */ orr r3, r3, #1 /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ str r3, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ /* Pop the registers that are not automatically saved on exception entry. */ ldmia r0!, {r3-r11, r14} msr control, r3 /* Restore the task stack pointer. */ msr psp, r0 mov r0, #0 msr basepri, r0 bx r14 /*-----------------------------------------------------------*/ vPortEnableVFP: /* The FPU enable bits are in the CPACR. */ ldr.w r0, =0xE000ED88 ldr r1, [r0] /* Enable CP10 and CP11 coprocessors, then save back. */ orr r1, r1, #( 0xf << 20 ) str r1, [r0] bx r14 /*-----------------------------------------------------------*/ xIsPrivileged: mrs r0, control /* r0 = CONTROL. */ tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ ite ne movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ vResetPrivilege: mrs r0, control /* r0 = CONTROL. */ orr r0, r0, #1 /* r0 = r0 | 1. */ msr control, r0 /* CONTROL = r0. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM4F_MPU/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* IAR includes. */ #include /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* MPU specific constants. */ #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #define portMPU_REGION_READ_WRITE ( 0x03UL << 24UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 0x05UL << 24UL ) #define portMPU_REGION_READ_ONLY ( 0x06UL << 24UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0x01UL << 24UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ( 0x02UL << 24UL ) #define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL ) #define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL ) /* Location of the TEX,S,C,B bits in the MPU Region Attribute and Size * Register (RASR). */ #define portMPU_RASR_TEX_S_C_B_LOCATION ( 16UL ) #define portMPU_RASR_TEX_S_C_B_MASK ( 0x3FUL ) /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* * The TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits define the * memory type, and where necessary the cacheable and shareable properties * of the memory region. * * The TEX, C, and B bits together indicate the memory type of the region, * and: * - For Normal memory, the cacheable properties of the region. * - For Device memory, whether the region is shareable. * * For Normal memory regions, the S bit indicates whether the region is * shareable. For Strongly-ordered and Device memory, the S bit is ignored. * * See the following two tables for setting TEX, S, C and B bits for * unprivileged flash, privileged flash and privileged RAM regions. * +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | TEX | C | B | Memory type | Description or Normal region cacheability | Shareable? | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 000 | 0 | 0 | Strongly-ordered | Strongly ordered | Shareable | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 000 | 0 | 1 | Device | Shared device | Shareable | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 000 | 1 | 0 | Normal | Outer and inner write-through; no write allocate | S bit | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 000 | 1 | 1 | Normal | Outer and inner write-back; no write allocate | S bit | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 001 | 0 | 0 | Normal | Outer and inner Non-cacheable | S bit | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 001 | 0 | 1 | Reserved | Reserved | Reserved | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 001 | 1 | 0 | IMPLEMENTATION DEFINED | IMPLEMENTATION DEFINED | IMPLEMENTATION DEFINED | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 001 | 1 | 1 | Normal | Outer and inner write-back; write and read allocate | S bit | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 010 | 0 | 0 | Device | Non-shared device | Not shareable | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 010 | 0 | 1 | Reserved | Reserved | Reserved | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 010 | 1 | X | Reserved | Reserved | Reserved | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 011 | X | X | Reserved | Reserved | Reserved | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 1BB | A | A | Normal | Cached memory, with AA and BB indicating the inner and | Reserved | | | | | | outer cacheability rules that must be exported on the | | | | | | | bus. See the table below for the cacheability policy | | | | | | | encoding. memory, BB=Outer policy, AA=Inner policy. | | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | +-----------------------------------------+----------------------------------------+ | AA or BB subfield of {TEX,C,B} encoding | Cacheability policy | +-----------------------------------------+----------------------------------------+ | 00 | Non-cacheable | +-----------------------------------------+----------------------------------------+ | 01 | Write-back, write and read allocate | +-----------------------------------------+----------------------------------------+ | 10 | Write-through, no write allocate | +-----------------------------------------+----------------------------------------+ | 11 | Write-back, no write allocate | +-----------------------------------------+----------------------------------------+ */ /* TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits for flash * region. */ #ifndef configTEX_S_C_B_FLASH /* Default to TEX=000, S=1, C=1, B=1 for backward compatibility. */ #define configTEX_S_C_B_FLASH ( 0x07UL ) #endif /* TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits for RAM * region. */ #ifndef configTEX_S_C_B_SRAM /* Default to TEX=000, S=1, C=1, B=1 for backward compatibility. */ #define configTEX_S_C_B_SRAM ( 0x07UL ) #endif #define portGENERAL_PERIPHERALS_REGION ( configTOTAL_MPU_REGIONS - 5UL ) #define portSTACK_REGION ( configTOTAL_MPU_REGIONS - 4UL ) #define portUNPRIVILEGED_FLASH_REGION ( configTOTAL_MPU_REGIONS - 3UL ) #define portPRIVILEGED_FLASH_REGION ( configTOTAL_MPU_REGIONS - 2UL ) #define portPRIVILEGED_RAM_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portFIRST_CONFIGURABLE_REGION ( 0UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 6UL ) #define portNUM_CONFIGURABLE_REGIONS ( configTOTAL_MPU_REGIONS - 5UL ) #define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus 1 to create space for the stack region. */ #define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, r0, #1 \n msr control, r0 " ::: "r0", "memory" ) typedef struct MPU_REGION_REGISTERS { uint32_t ulRegionBaseAddress; uint32_t ulRegionAttribute; } xMPU_REGION_REGISTERS; typedef struct MPU_SETTINGS { xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ]; } xMPU_SETTINGS; /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* SVC numbers for various services. */ #define portSVC_START_SCHEDULER 0 #define portSVC_YIELD 1 #define portSVC_RAISE_PRIVILEGE 2 /* Scheduler utilities. */ #define portYIELD() __asm volatile ( " SVC %0 \n"::"i" ( portSVC_YIELD ) : "memory" ) #define portYIELD_WITHIN_API() \ { \ /* Set a PendSV to request a context switch. */ \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ __DSB(); \ __ISB(); \ } #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD_WITHIN_API(); } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 ) /* Check the configuration. */ #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. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) __CLZ( ( uxReadyPriorities ) ) ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); #if( configENABLE_ERRATA_837070_WORKAROUND == 1 ) #define portDISABLE_INTERRUPTS() \ { \ __disable_interrupt(); \ __set_BASEPRI( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \ __DSB(); \ __ISB(); \ __enable_interrupt(); \ } #else #define portDISABLE_INTERRUPTS() \ { \ __set_BASEPRI( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \ __DSB(); \ __ISB(); \ } #endif #define portENABLE_INTERRUPTS() __set_BASEPRI( 0 ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() #define portSET_INTERRUPT_MASK_FROM_ISR() __get_BASEPRI(); portDISABLE_INTERRUPTS() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) __set_BASEPRI( x ) /*-----------------------------------------------------------*/ /* 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 * (which build with all the ports) will build. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* portNOP() is not required by this port. */ #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif /*-----------------------------------------------------------*/ portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ extern BaseType_t xIsPrivileged( void ); extern void vResetPrivilege( void ); /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() /*-----------------------------------------------------------*/ #ifndef configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY #warning "configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY is not defined. We recommend defining it to 1 in FreeRTOSConfig.h for better security. https://www.FreeRTOS.org/FreeRTOS-V10.3.x.html" #define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 0 #endif /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Pe191 #pragma diag_suppress=Pa082 #pragma diag_suppress=Be006 /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55/non_secure/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /* Portasm includes. */ #include "portasm.h" #if ( configENABLE_TRUSTZONE == 1 ) /* Secure components includes. */ #include "secure_context.h" #include "secure_init.h" #endif /* configENABLE_TRUSTZONE */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /** * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS * on the secure side. The following are the valid configuration seetings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 * * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 * * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 */ #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. #endif /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the SCB. */ #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the FPU. */ #define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) #define portMPU_RLAR_REGION_ENABLE ( 1UL ) /* Enable privileged access to unmapped region. */ #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /*-----------------------------------------------------------*/ /** * @brief The maximum 24-bit number. * * It is needed because the systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /** * @brief A fiddle factor to estimate the number of SysTick counts that would * have occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) /** * @brief Initial EXC_RETURN value. * * FF FF FF FD * 1111 1111 1111 1111 1111 1111 1111 1101 * * Bit[6] - 1 --> The exception was taken from the Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 1 --> The exception was taken to the Secure state. */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else /** * @brief Initial EXC_RETURN value. * * FF FF FF BC * 1111 1111 1111 1111 1111 1111 1011 1100 * * Bit[6] - 0 --> The exception was taken from the Non-Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 0 --> The exception was taken to the Non-Secure state. */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ /** * @brief CONTROL register privileged bit mask. * * Bit[0] in CONTROL register tells the privilege: * Bit[0] = 0 ==> The task is privileged. * Bit[0] = 1 ==> The task is not privileged. */ #define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) /** * @brief Initial CONTROL register values. */ #define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) #define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) /** * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /** * @brief 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /** * @brief If portPRELOAD_REGISTERS then registers will be given an initial value * when a task is created. This helps in debugging at the cost of code size. */ #define portPRELOAD_REGISTERS 1 /** * @brief A task is created without a secure context, and must call * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes * any secure calls. */ #define portNO_SECURE_CONTEXT 0 /*-----------------------------------------------------------*/ /** * @brief Used to catch tasks that attempt to return from their implementing * function. */ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) /** * @brief Setup the Memory Protection Unit (MPU). */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) /** * @brief Setup the Floating Point Unit (FPU). */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ /** * @brief Setup the timer to generate the tick interrupts. * * The implementation in this file is weak to allow application writers to * change the timer used to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /** * @brief Checks whether the current execution context is interrupt. * * @return pdTRUE if the current execution context is interrupt, pdFALSE * otherwise. */ BaseType_t xPortIsInsideInterrupt( void ); /** * @brief Yield the processor. */ void vPortYield( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ void vPortExitCritical( void ) PRIVILEGED_FUNCTION; /** * @brief SysTick handler. */ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; /** * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. */ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Saved as part of the task context to indicate which context the * task is using on the secure side. */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ #if ( configUSE_TICKLESS_IDLE == 1 ) /** * @brief The number of SysTick increments that make up one tick period. */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; /** * @brief The maximum number of tick periods that can be suppressed is * limited by the 24 bit resolution of the SysTick timer. */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; /** * @brief Compensate for the CPU cycles that pass while the SysTick is * stopped (low power functionality only). */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). Artificially force an assert() * to be triggered if configASSERT() is defined, then stop here so * application writers can catch the error. */ configASSERT( ulCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being * defined but never called. ulDummy is used purely to quieten other * warnings about code appearing after this function is called - making * ulDummy volatile makes the compiler think the function could return * and therefore not output an 'unreachable code' warning for code that * appears after it. */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; extern uint32_t * __unprivileged_flash_start__; extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* if defined( __ARMCC_VERSION ) */ /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; extern uint32_t __unprivileged_flash_start__[]; extern uint32_t __unprivileged_flash_end__[]; extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check that the MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* MAIR0 - Index 0. */ portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); /* MAIR0 - Index 1. */ portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* Setup privileged flash as Read Only so that privileged tasks can * read it but not modify. */ portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged flash as Read Only by both privileged and * unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged syscalls flash as Read Only by both privileged * and unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup RAM containing kernel data for privileged access only. */ portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Enable mem fault. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; /* Enable MPU with privileged background access i.e. unmapped * regions have privileged access. */ portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) { /* Enable non-secure access to the FPU. */ SecureInit_EnableNSFPUAccess(); } #endif /* configENABLE_TRUSTZONE */ /* CP10 = 11 ==> Full access to FPU i.e. both privileged and * unprivileged code should be able to access FPU. CP11 should be * programmed to the same value as CP10. */ *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) ); /* ASPEN = 1 ==> Hardware should automatically preserve floating point * context on exception entry and restore on exception return. * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ void vPortYield( void ) /* PRIVILEGED_FUNCTION */ { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ { portDISABLE_INTERRUPTS(); ulCriticalNesting++; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ { configASSERT( ulCriticalNesting ); ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { #if ( configENABLE_MPU == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ #endif /* configENABLE_MPU */ uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) uint32_t ulR0, ulR1; extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ #endif /* configENABLE_TRUSTZONE */ uint8_t ucSVCNumber; /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ ulPC = pulCallerStackAddress[ 6 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { #if ( configENABLE_TRUSTZONE == 1 ) case portSVC_ALLOCATE_SECURE_CONTEXT: /* R0 contains the stack size passed as parameter to the * vPortAllocateSecureContext function. */ ulR0 = pulCallerStackAddress[ 0 ]; #if ( configENABLE_MPU == 1 ) { /* Read the CONTROL register value. */ __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); /* The task that raised the SVC is privileged if Bit[0] * in the CONTROL register is 0. */ ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: /* R0 contains TCB being freed and R1 contains the secure * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) { /* De-prioritize the non-secure exceptions so that the * non-secure pendSV runs at the lowest priority. */ SecureInit_DePrioritizeNSExceptions(); /* Initialize the secure context management system. */ SecureContext_Init(); } #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_FPU == 1 ) { /* Setup the Floating Point Unit (FPU). */ prvSetupFPU(); } #endif /* configENABLE_FPU */ /* Setup the context of the first task so that the first task starts * executing. */ vRestoreContextOfFirstTask(); break; #if ( configENABLE_MPU == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the svc was raised from any of * the system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { vRaisePrivilege(); } break; #endif /* configENABLE_MPU */ default: /* Incorrect SVC call. */ configASSERT( pdFALSE ); } } /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #if ( configENABLE_MPU == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /* *INDENT-ON* */ { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #endif /* portPRELOAD_REGISTERS */ return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ prvSetupMPU(); } #endif /* configENABLE_MPU */ /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; /* Start the first task. */ vStartFirstTask(); /* Should never get here as the tasks will now be executing. Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* Setup MAIR0. */ xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ if( ulStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged * SRAM is already protected using an MPU region and ARMv8-M does * not allow overlapping MPU regions. */ if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) { xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; } else { /* Define the region that allows access to the stack. */ ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); } } /* User supplied configurable regions. */ for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) { /* If xRegions is NULL i.e. the task has not specified any MPU * region, the else part ensures that all the configurable MPU * regions are invalidated. */ if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) { /* Translate the generic region definition contained in xRegions * into the ARMv8 specific MPU settings that are then stored in * xMPUSettings. */ ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; /* Start address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ); /* RO/RW. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); } else { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); } /* XN. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); } /* End Address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { /* Attr1 in MAIR0 is configured as device memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; } else { /* Attr0 in MAIR0 is configured as normal memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; } } else { /* Invalidate the region. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; } lIndex++; } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. Interrupt Program * Status Register (IPSR) holds the exception number of the currently-executing * exception or zero for Thread mode.*/ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55/non_secure/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORT_ASM_H__ #define __PORT_ASM_H__ /* Scheduler includes. */ #include "FreeRTOS.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /** * @brief Restore the context of the first task so that the first task starts * executing. */ void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * * @note This is a privileged function and should only be called from the kenrel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Starts the first task. */ void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Disables interrupts. */ uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Enables interrupts. */ void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief PendSV Exception handler. */ void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief SVC Handler. */ void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Allocate a Secure context for the calling task. * * @param[in] ulSecureStackSize The size of the stack to be allocated on the * secure side for the calling task. */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); /** * @brief Free the task's secure context. * * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. */ void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* __PORT_ASM_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55/non_secure/portasm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C EXTERN SecureContext_SaveContext EXTERN SecureContext_LoadContext PUBLIC xIsPrivileged PUBLIC vResetPrivilege PUBLIC vPortAllocateSecureContext PUBLIC vRestoreContextOfFirstTask PUBLIC vRaisePrivilege PUBLIC vStartFirstTask PUBLIC ulSetInterruptMask PUBLIC vClearInterruptMask PUBLIC PendSV_Handler PUBLIC SVC_Handler PUBLIC vPortFreeSecureContext /*-----------------------------------------------------------*/ /*---------------- Unprivileged Functions -------------------*/ /*-----------------------------------------------------------*/ SECTION .text:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ xIsPrivileged: mrs r0, control /* r0 = CONTROL. */ tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ ite ne movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ vResetPrivilege: mrs r0, control /* r0 = CONTROL. */ orr r0, r0, #1 /* r0 = r0 | 1. */ msr control, r0 /* CONTROL = r0. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vPortAllocateSecureContext: svc 0 /* Secure context is allocated in the supervisor call. portSVC_ALLOCATE_SECURE_CONTEXT = 0. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ /*----------------- Privileged Functions --------------------*/ /*-----------------------------------------------------------*/ SECTION privileged_functions:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ str r4, [r2] /* Disable MPU. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r4, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ movs r4, #4 /* r4 = 4. */ str r4, [r2] /* Program RNR = 4. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldmia r3!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ str r4, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ ldr r5, =xSecureContext str r1, [r5] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ msr control, r3 /* Set this task's CONTROL value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r4 /* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r3 /* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ vRaisePrivilege: mrs r0, control /* Read the CONTROL register. */ bic r0, r0, #1 /* Clear the bit 0. */ msr control, r0 /* Write back the new CONTROL value. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vStartFirstTask: ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ ldr r0, [r0] /* The first entry in vector table is stack pointer. */ msr msp, r0 /* Set the MSP back to the start of the stack. */ cpsie i /* Globally enable interrupts. */ cpsie f dsb isb svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ /*-----------------------------------------------------------*/ ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ /*-----------------------------------------------------------*/ vClearInterruptMask: msr basepri, r0 /* basepri = ulMask. */ dsb isb bx lr /* Return. */ /*-----------------------------------------------------------*/ PendSV_Handler: ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ push {r0-r2, r14} bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r0-r3} /* LR is now in r3. */ mov lr, r3 /* LR = r3. */ lsls r1, r3, #25 /* 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 /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ b select_next_task save_ns_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ adds r2, r2, #16 /* r2 = r2 + 16. */ stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ subs r2, r2, #16 /* r2 = r2 - 16. */ stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ adds r2, r2, #12 /* r2 = r2 + 12. */ stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ subs r2, r2, #12 /* r2 = r2 - 12. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r3] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ str r4, [r3] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ str r4, [r3] /* Program MAIR0. */ ldr r3, =0xe000ed98 /* r3 = 0xe000ed98 [Location of RNR]. */ movs r4, #4 /* r4 = 4. */ str r4, [r3] /* Program RNR = 4. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ stmia r3!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r3] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ str r4, [r3] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ msr control, r3 /* Restore the CONTROL register value for the task. */ mov lr, r4 /* LR = r4. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ push {r2, r4} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r2, r4} mov lr, r4 /* LR = r4. */ lsls r1, r4, #25 /* 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 /* 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 /* Remember the new top of stack for the task. */ bx lr #else /* configENABLE_MPU */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ push {r2, r4} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r2, r4} mov lr, r4 /* LR = r4. */ lsls r1, r4, #25 /* 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 /* 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 /* Remember the new top of stack for the task. */ bx lr #endif /* configENABLE_MPU */ restore_ns_context: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ msr psp, r2 /* Remember the new top of stack for the task. */ bx lr /*-----------------------------------------------------------*/ SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp b vPortSVCHandler_C /*-----------------------------------------------------------*/ vPortFreeSecureContext: /* r0 = uint32_t *pulTCB. */ ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ it ne svcne 1 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 1. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55/non_secure/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_MVE #error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE. #endif /* configENABLE_MVE */ /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M55" #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Be006 #pragma diag_suppress=Pa082 /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACROCOMMON_H #define PORTMACROCOMMON_H #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_FPU #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. #endif /* configENABLE_FPU */ #ifndef configENABLE_MPU #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. #endif /* configENABLE_MPU */ #ifndef configENABLE_TRUSTZONE #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ /** * @brief Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif #define portHAS_STACK_OVERFLOW_CHECKING 1 /*-----------------------------------------------------------*/ /** * @brief Extern declarations. */ extern BaseType_t xPortIsInsideInterrupt( void ); extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; #if ( configENABLE_TRUSTZONE == 1 ) extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_MPU == 1 ) extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief MPU specific constants. */ #if ( configENABLE_MPU == 1 ) #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #else #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* MPU regions. */ #define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_RAM_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ /* Device memory attributes used in MPU_MAIR registers. * * 8-bit values encoded as follows: * Bit[7:4] - 0000 - Device Memory * Bit[3:2] - 00 --> Device-nGnRnE * 01 --> Device-nGnRE * 10 --> Device-nGRE * 11 --> Device-GRE * Bit[1:0] - 00, Reserved. */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ /* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ /* Attributes used in MPU_RBAR registers. */ #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ /** * @brief Settings to define an MPU region. */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */ } MPURegionSettings_t; /** * @brief MPU settings as stored in the TCB. */ typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ } xMPU_SETTINGS; /*-----------------------------------------------------------*/ /** * @brief SVC numbers. */ #define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 /*-----------------------------------------------------------*/ /** * @brief Scheduler utilities. */ #define portYIELD() vPortYield() #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /** * @brief Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /** * @brief Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Allocate a secure context for the task. * * 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 context before it calls any secure function. * * @param[in] ulSecureStackSize The size of the secure stack to be allocated. */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) /** * @brief Called when a task is deleted to delete the task's secure context, * if it has one. * * @param[in] pxTCB The TCB of the task being deleted. */ #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. * * 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, * the privilege is not raised. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() #else #define portIS_PRIVILEGED() #define portRAISE_PRIVILEGE() #define portRESET_PRIVILEGE() #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief Barriers. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACROCOMMON_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55/secure/secure_context.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Secure context includes. */ #include "secure_context.h" /* Secure heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief CONTROL value for privileged tasks. * * Bit[0] - 0 --> Thread mode is privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_PRIVILEGED 0x02 /** * @brief CONTROL value for un-privileged tasks. * * Bit[0] - 1 --> Thread mode is un-privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 /** * @brief Size of stack seal values in bytes. */ #define securecontextSTACK_SEAL_SIZE 8 /** * @brief Stack seal value as recommended by ARM. */ #define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5 /** * @brief Maximum number of secure contexts. */ #ifndef secureconfigMAX_SECURE_CONTEXTS #define secureconfigMAX_SECURE_CONTEXTS 8UL #endif /*-----------------------------------------------------------*/ /** * @brief Pre-allocated array of secure contexts. */ SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ]; /*-----------------------------------------------------------*/ /** * @brief Get a free secure context for a task from the secure context pool (xSecureContexts). * * This function ensures that only one secure context is allocated for a task. * * @param[in] pvTaskHandle The task handle for which the secure context is allocated. * * @return Index of a free secure context in the xSecureContexts array. */ static uint32_t ulGetSecureContext( void * pvTaskHandle ); /** * @brief Return the secure context to the secure context pool (xSecureContexts). * * @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array. */ static void vReturnSecureContext( uint32_t ulSecureContextIndex ); /* These are implemented in assembly. */ extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ); extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ); /*-----------------------------------------------------------*/ static uint32_t ulGetSecureContext( void * pvTaskHandle ) { /* Start with invalid index. */ uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) && ( xSecureContexts[ i ].pucStackLimit == NULL ) && ( xSecureContexts[ i ].pucStackStart == NULL ) && ( xSecureContexts[ i ].pvTaskHandle == NULL ) && ( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = i; } else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle ) { /* A task can only have one secure context. Do not allocate a second * context for the same task. */ ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; break; } } return ulSecureContextIndex; } /*-----------------------------------------------------------*/ static void vReturnSecureContext( uint32_t ulSecureContextIndex ) { xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) { uint32_t ulIPSR, i; static uint32_t ulSecureContextsInitialized = 0; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) ) { /* Ensure to initialize secure contexts only once. */ ulSecureContextsInitialized = 1; /* No stack for thread mode until a task's context is loaded. */ secureportSET_PSPLIM( securecontextNO_STACK ); secureportSET_PSP( securecontextNO_STACK ); /* Initialize all secure contexts. */ for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { xSecureContexts[ i ].pucCurrentStackPointer = NULL; xSecureContexts[ i ].pucStackLimit = NULL; xSecureContexts[ i ].pucStackStart = NULL; xSecureContexts[ i ].pvTaskHandle = NULL; } #if ( configENABLE_MPU == 1 ) { /* Configure thread mode to use PSP and to be unprivileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED ); } #else /* configENABLE_MPU */ { /* Configure thread mode to use PSP and to be privileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED ); } #endif /* configENABLE_MPU */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ) #else /* configENABLE_MPU */ secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ) #endif /* configENABLE_MPU */ { uint8_t * pucStackMemory = NULL; uint8_t * pucStackLimit; uint32_t ulIPSR, ulSecureContextIndex; SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID; #if ( configENABLE_MPU == 1 ) uint32_t * pulCurrentStackPointer = NULL; #endif /* configENABLE_MPU */ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit * Register (PSPLIM) value. */ secureportREAD_IPSR( ulIPSR ); secureportREAD_PSPLIM( pucStackLimit ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. * Also do nothing, if a secure context us already loaded. PSPLIM is set to * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { /* Ontain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space. */ pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE ); if( pucStackMemory != NULL ) { /* Since stack grows down, the starting point will be the last * location. Note that this location is next to the last * allocated byte for stack (excluding the space for seal values) * because the hardware decrements the stack pointer before * writing i.e. if stack pointer is 0x2, a push operation will * decrement the stack pointer to 0x1 and then write at 0x1. */ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize; /* Seal the created secure process stack. */ *( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE; *( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE; /* The stack cannot go beyond this location. This value is * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle; #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 ) { *( 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 /* configENABLE_MPU */ { /* Current SP is set to the starting of the stack. This * value programmed in the PSP register on context switch. */ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart; } #endif /* configENABLE_MPU */ /* Ensure to never return 0 as a valid context handle. */ xSecureContextHandle = ulSecureContextIndex + 1UL; } } } return xSecureContextHandle; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint32_t ulIPSR, ulSecureContextIndex; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* Only free if a valid context handle is passed. */ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; /* Ensure that the secure context being deleted is associated with * the task. */ if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) { /* Free the stack space. */ vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); /* Return the secure context back to the free secure contexts pool. */ vReturnSecureContext( ulSecureContextIndex ); } } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that no secure context is loaded and the task is loading it's * own context. */ if( ( pucStackLimit == securecontextNO_STACK ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that task's context is loaded and the task is saving it's own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55/secure/secure_context.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_CONTEXT_H__ #define __SECURE_CONTEXT_H__ /* Standard includes. */ #include /* FreeRTOS includes. */ #include "FreeRTOSConfig.h" /** * @brief PSP value when no secure context is loaded. */ #define securecontextNO_STACK 0x0 /** * @brief Invalid context ID. */ #define securecontextINVALID_CONTEXT_ID 0UL /*-----------------------------------------------------------*/ /** * @brief Structure to represent a secure context. * * @note Since stack grows down, pucStackStart is the highest address while * pucStackLimit is the first address of the allocated memory. */ typedef struct SecureContext { uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */ uint8_t * pucStackStart; /**< First location of the stack memory. */ void * pvTaskHandle; /**< Task handle of the task this context is associated with. */ } SecureContext_t; /*-----------------------------------------------------------*/ /** * @brief Opaque handle for a secure context. */ typedef uint32_t SecureContextHandle_t; /*-----------------------------------------------------------*/ /** * @brief Initializes the secure context management system. * * PSP is set to NULL and therefore a task must allocate and load a context * before calling any secure side function in the thread mode. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureContext_Init( void ); /** * @brief Allocates a context on the secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] ulSecureStackSize Size of the stack to allocate on secure side. * @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise. * * @return Opaque context handle if context is successfully allocated, NULL * otherwise. */ #if ( configENABLE_MPU == 1 ) SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ); #else /* configENABLE_MPU */ SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ); #endif /* configENABLE_MPU */ /** * @brief Frees the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the * context to be freed. */ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Loads the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be loaded. */ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Saves the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be saved. */ void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); #endif /* __SECURE_CONTEXT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55/secure/secure_context_port_asm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ SECTION .text:CODE:NOROOT(2) THUMB /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" PUBLIC SecureContext_LoadContextAsm PUBLIC SecureContext_SaveContextAsm /*-----------------------------------------------------------*/ SecureContext_LoadContextAsm: /* pxSecureContext value is in r0. */ mrs r1, ipsr /* r1 = IPSR. */ cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ ldmia r0!, {r1, r2} /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */ #if ( configENABLE_MPU == 1 ) ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */ msr control, r3 /* CONTROL = r3. */ #endif /* configENABLE_MPU */ msr psplim, r2 /* PSPLIM = r2. */ msr psp, r1 /* PSP = r1. */ load_ctx_therad_mode: bx lr /*-----------------------------------------------------------*/ SecureContext_SaveContextAsm: /* pxSecureContext value is in r0. */ mrs r1, ipsr /* r1 = IPSR. */ cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ mrs r1, psp /* r1 = PSP. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) vstmdb r1!, {s0} /* Trigger the deferred stacking of FPU registers. */ vldmia r1!, {s0} /* Nullify the effect of the previous statement. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) mrs r2, control /* r2 = CONTROL. */ stmdb r1!, {r2} /* Store CONTROL value on the stack. */ #endif /* configENABLE_MPU */ str r1, [r0] /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ movs r1, #0 /* r1 = securecontextNO_STACK. */ msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */ msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */ save_ctx_therad_mode: bx lr /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55/secure/secure_heap.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure context heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Total heap size. */ #ifndef secureconfigTOTAL_HEAP_SIZE #define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) ) #endif /* No test marker by default. */ #ifndef mtCOVERAGE_TEST_MARKER #define mtCOVERAGE_TEST_MARKER() #endif /* No tracing by default. */ #ifndef traceMALLOC #define traceMALLOC( pvReturn, xWantedSize ) #endif /* No tracing by default. */ #ifndef traceFREE #define traceFREE( pv, xBlockSize ) #endif /* Block sizes must not get too small. */ #define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) /* Assumes 8bit bytes! */ #define secureheapBITS_PER_BYTE ( ( size_t ) 8 ) /*-----------------------------------------------------------*/ /* Allocate the memory for the heap. */ #if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) /* The application writer has already defined the array used for the RTOS * heap - probably so it can be placed in a special segment or address. */ extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #else /* configAPPLICATION_ALLOCATED_HEAP */ static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #endif /* configAPPLICATION_ALLOCATED_HEAP */ /** * @brief The linked list structure. * * This is used to link free blocks in order of their memory address. */ typedef struct A_BLOCK_LINK { struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */ size_t xBlockSize; /**< The size of the free block. */ } BlockLink_t; /*-----------------------------------------------------------*/ /** * @brief Called automatically to setup the required heap structures the first * time pvPortMalloc() is called. */ static void prvHeapInit( void ); /** * @brief Inserts a block of memory that is being freed into the correct * position in the list of free memory blocks. * * The block being freed will be merged with the block in front it and/or the * block behind it if the memory blocks are adjacent to each other. * * @param[in] pxBlockToInsert The block being freed. */ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ); /*-----------------------------------------------------------*/ /** * @brief The size of the structure placed at the beginning of each allocated * memory block must by correctly byte aligned. */ static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); /** * @brief Create a couple of list links to mark the start and end of the list. */ static BlockLink_t xStart; static BlockLink_t * pxEnd = NULL; /** * @brief Keeps track of the number of free bytes remaining, but says nothing * about fragmentation. */ static size_t xFreeBytesRemaining = 0U; static size_t xMinimumEverFreeBytesRemaining = 0U; /** * @brief Gets set to the top bit of an size_t type. * * When this bit in the xBlockSize member of an BlockLink_t structure is set * then the block belongs to the application. When the bit is free the block is * still part of the free heap space. */ static size_t xBlockAllocatedBit = 0; /*-----------------------------------------------------------*/ static void prvHeapInit( void ) { BlockLink_t * pxFirstFreeBlock; uint8_t * pucAlignedHeap; size_t uxAddress; size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE; /* Ensure the heap starts on a correctly aligned boundary. */ uxAddress = ( size_t ) ucHeap; if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 ) { uxAddress += ( secureportBYTE_ALIGNMENT - 1 ); uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; } pucAlignedHeap = ( uint8_t * ) uxAddress; /* xStart is used to hold a pointer to the first item in the list of free * blocks. The void cast is used to prevent compiler warnings. */ xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; xStart.xBlockSize = ( size_t ) 0; /* pxEnd is used to mark the end of the list of free blocks and is inserted * at the end of the heap space. */ uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; uxAddress -= xHeapStructSize; uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); pxEnd = ( void * ) uxAddress; pxEnd->xBlockSize = 0; pxEnd->pxNextFreeBlock = NULL; /* To start with there is a single free block that is sized to take up the * entire heap space, minus the space taken by pxEnd. */ pxFirstFreeBlock = ( void * ) pucAlignedHeap; pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; pxFirstFreeBlock->pxNextFreeBlock = pxEnd; /* Only one block exists - and it covers the entire usable heap space. */ xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; /* Work out the position of the top bit in a size_t variable. */ xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 ); } /*-----------------------------------------------------------*/ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) { BlockLink_t * pxIterator; uint8_t * puc; /* Iterate through the list until a block is found that has a higher address * than the block being inserted. */ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) { /* Nothing to do here, just iterate to the right position. */ } /* Do the block being inserted, and the block it is being inserted after * make a contiguous block of memory? */ puc = ( uint8_t * ) pxIterator; if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) { pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; pxBlockToInsert = pxIterator; } else { mtCOVERAGE_TEST_MARKER(); } /* Do the block being inserted, and the block it is being inserted before * make a contiguous block of memory? */ puc = ( uint8_t * ) pxBlockToInsert; if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) { if( pxIterator->pxNextFreeBlock != pxEnd ) { /* Form one big block from the two blocks. */ pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; } else { pxBlockToInsert->pxNextFreeBlock = pxEnd; } } else { pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } /* If the block being inserted plugged a gab, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ if( pxIterator != pxBlockToInsert ) { pxIterator->pxNextFreeBlock = pxBlockToInsert; } else { mtCOVERAGE_TEST_MARKER(); } } /*-----------------------------------------------------------*/ void * pvPortMalloc( size_t xWantedSize ) { BlockLink_t * pxBlock; BlockLink_t * pxPreviousBlock; BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ if( pxEnd == NULL ) { prvHeapInit(); } else { mtCOVERAGE_TEST_MARKER(); } /* Check the requested block size is not so large that the top bit is set. * The top bit of the block size member of the BlockLink_t structure is used * to determine who owns the block - the application or the kernel, so it * must be free. */ if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) { /* The wanted size is increased so it can contain a BlockLink_t * structure in addition to the requested amount of bytes. */ if( xWantedSize > 0 ) { xWantedSize += xHeapStructSize; /* Ensure that blocks are always aligned to the required number of * bytes. */ if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 ) { /* Byte alignment required. */ xWantedSize += ( secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) ); secureportASSERT( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) == 0 ); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) { /* Traverse the list from the start (lowest address) block until * one of adequate size is found. */ pxPreviousBlock = &xStart; pxBlock = xStart.pxNextFreeBlock; while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) { pxPreviousBlock = pxBlock; pxBlock = pxBlock->pxNextFreeBlock; } /* If the end marker was reached then a block of adequate size was * not found. */ if( pxBlock != pxEnd ) { /* Return the memory space pointed to - jumping over the * BlockLink_t structure at its start. */ pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); /* This block is being returned for use so must be taken out * of the list of free blocks. */ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; /* If the block is larger than required it can be split into * two. */ if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE ) { /* This block is to be split into two. Create a new * block following the number of bytes requested. The void * cast is used to prevent byte alignment warnings from the * compiler. */ pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 ); /* Calculate the sizes of two blocks split from the single * block. */ pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; pxBlock->xBlockSize = xWantedSize; /* Insert the new block into the list of free blocks. */ prvInsertBlockIntoFreeList( pxNewBlockLink ); } else { mtCOVERAGE_TEST_MARKER(); } xFreeBytesRemaining -= pxBlock->xBlockSize; if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) { xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; } else { mtCOVERAGE_TEST_MARKER(); } /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ pxBlock->xBlockSize |= xBlockAllocatedBit; pxBlock->pxNextFreeBlock = NULL; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } traceMALLOC( pvReturn, xWantedSize ); #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { extern void vApplicationMallocFailedHook( void ); vApplicationMallocFailedHook(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */ secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 ); return pvReturn; } /*-----------------------------------------------------------*/ void vPortFree( void * pv ) { uint8_t * puc = ( uint8_t * ) pv; BlockLink_t * pxLink; if( pv != NULL ) { /* The memory being freed will have an BlockLink_t structure immediately * before it. */ puc -= xHeapStructSize; /* This casting is to keep the compiler from issuing warnings. */ pxLink = ( void * ) puc; /* Check the block is actually allocated. */ secureportASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); secureportASSERT( pxLink->pxNextFreeBlock == NULL ); if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) { if( pxLink->pxNextFreeBlock == NULL ) { /* The block is being returned to the heap - it is no longer * allocated. */ pxLink->xBlockSize &= ~xBlockAllocatedBit; secureportDISABLE_NON_SECURE_INTERRUPTS(); { /* Add this block to the list of free blocks. */ xFreeBytesRemaining += pxLink->xBlockSize; traceFREE( pv, pxLink->xBlockSize ); prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); } secureportENABLE_NON_SECURE_INTERRUPTS(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } } /*-----------------------------------------------------------*/ size_t xPortGetFreeHeapSize( void ) { return xFreeBytesRemaining; } /*-----------------------------------------------------------*/ size_t xPortGetMinimumEverFreeHeapSize( void ) { return xMinimumEverFreeBytesRemaining; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55/secure/secure_heap.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_HEAP_H__ #define __SECURE_HEAP_H__ /* Standard includes. */ #include /** * @brief Allocates memory from heap. * * @param[in] xWantedSize The size of the memory to be allocated. * * @return Pointer to the memory region if the allocation is successful, NULL * otherwise. */ void * pvPortMalloc( size_t xWantedSize ); /** * @brief Frees the previously allocated memory. * * @param[in] pv Pointer to the memory to be freed. */ void vPortFree( void * pv ); /** * @brief Get the free heap size. * * @return Free heap size. */ size_t xPortGetFreeHeapSize( void ); /** * @brief Get the minimum ever free heap size. * * @return Minimum ever free heap size. */ size_t xPortGetMinimumEverFreeHeapSize( void ); #endif /* __SECURE_HEAP_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55/secure/secure_init.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure init includes. */ #include "secure_init.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Constants required to manipulate the SCB. */ #define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */ #define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL ) #define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS ) #define secureinitSCB_AIRCR_PRIS_POS ( 14UL ) #define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS ) /** * @brief Constants required to manipulate the FPU. */ #define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define secureinitFPCCR_LSPENS_POS ( 29UL ) #define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS ) #define secureinitFPCCR_TS_POS ( 26UL ) #define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS ) #define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */ #define secureinitNSACR_CP10_POS ( 10UL ) #define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS ) #define secureinitNSACR_CP11_POS ( 11UL ) #define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS ) /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { *( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) | ( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) | ( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK ); } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* CP10 = 1 ==> Non-secure access to the Floating Point Unit is * permitted. CP11 should be programmed to the same value as CP10. */ *( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK ); /* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures * that we can enable/disable lazy stacking in port.c file. */ *( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK ); /* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP * registers (S16-S31) are also pushed to stack on exception entry and * restored on exception return. */ *( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK ); } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55/secure/secure_init.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_INIT_H__ #define __SECURE_INIT_H__ /** * @brief De-prioritizes the non-secure exceptions. * * This is needed to ensure that the non-secure PendSV runs at the lowest * priority. Context switch is done in the non-secure PendSV handler. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_DePrioritizeNSExceptions( void ); /** * @brief Sets up the Floating Point Unit (FPU) for Non-Secure access. * * Also sets FPCCR.TS=1 to ensure that the content of the Floating Point * Registers are not leaked to the non-secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_EnableNSFPUAccess( void ); #endif /* __SECURE_INIT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55/secure/secure_port_macros.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_PORT_MACROS_H__ #define __SECURE_PORT_MACROS_H__ /** * @brief Byte alignment requirements. */ #define secureportBYTE_ALIGNMENT 8 #define secureportBYTE_ALIGNMENT_MASK ( 0x0007 ) /** * @brief Macro to declare a function as non-secure callable. */ #if defined( __IAR_SYSTEMS_ICC__ ) #define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root #else #define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) ) #endif /** * @brief Set the secure PRIMASK value. */ #define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Set the non-secure PRIMASK value. */ #define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Read the PSP value in the given variable. */ #define secureportREAD_PSP( pucOutCurrentStackPointer ) \ __asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) ) /** * @brief Set the PSP to the given value. */ #define secureportSET_PSP( pucCurrentStackPointer ) \ __asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) ) /** * @brief Read the PSPLIM value in the given variable. */ #define secureportREAD_PSPLIM( pucOutStackLimit ) \ __asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) ) /** * @brief Set the PSPLIM to the given value. */ #define secureportSET_PSPLIM( pucStackLimit ) \ __asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) ) /** * @brief Set the NonSecure MSP to the given value. */ #define secureportSET_MSP_NS( pucMainStackPointer ) \ __asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) ) /** * @brief Set the CONTROL register to the given value. */ #define secureportSET_CONTROL( ulControl ) \ __asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" ) /** * @brief Read the Interrupt Program Status Register (IPSR) value in the given * variable. */ #define secureportREAD_IPSR( ulIPSR ) \ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) ) /** * @brief PRIMASK value to enable interrupts. */ #define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0 /** * @brief PRIMASK value to disable interrupts. */ #define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1 /** * @brief Disable secure interrupts. */ #define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Disable non-secure interrupts. * * This effectively disables context switches. */ #define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Enable non-secure interrupts. */ #define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL ) /** * @brief Assert definition. */ #define secureportASSERT( x ) \ if( ( x ) == 0 ) \ { \ secureportDISABLE_SECURE_INTERRUPTS(); \ secureportDISABLE_NON_SECURE_INTERRUPTS(); \ for( ; ; ) {; } \ } #endif /* __SECURE_PORT_MACROS_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55_NTZ/non_secure/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /* Portasm includes. */ #include "portasm.h" #if ( configENABLE_TRUSTZONE == 1 ) /* Secure components includes. */ #include "secure_context.h" #include "secure_init.h" #endif /* configENABLE_TRUSTZONE */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /** * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS * on the secure side. The following are the valid configuration seetings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 * * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 * * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 */ #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. #endif /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the SCB. */ #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the FPU. */ #define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) #define portMPU_RLAR_REGION_ENABLE ( 1UL ) /* Enable privileged access to unmapped region. */ #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /*-----------------------------------------------------------*/ /** * @brief The maximum 24-bit number. * * It is needed because the systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /** * @brief A fiddle factor to estimate the number of SysTick counts that would * have occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) /** * @brief Initial EXC_RETURN value. * * FF FF FF FD * 1111 1111 1111 1111 1111 1111 1111 1101 * * Bit[6] - 1 --> The exception was taken from the Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 1 --> The exception was taken to the Secure state. */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else /** * @brief Initial EXC_RETURN value. * * FF FF FF BC * 1111 1111 1111 1111 1111 1111 1011 1100 * * Bit[6] - 0 --> The exception was taken from the Non-Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 0 --> The exception was taken to the Non-Secure state. */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ /** * @brief CONTROL register privileged bit mask. * * Bit[0] in CONTROL register tells the privilege: * Bit[0] = 0 ==> The task is privileged. * Bit[0] = 1 ==> The task is not privileged. */ #define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) /** * @brief Initial CONTROL register values. */ #define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) #define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) /** * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /** * @brief 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /** * @brief If portPRELOAD_REGISTERS then registers will be given an initial value * when a task is created. This helps in debugging at the cost of code size. */ #define portPRELOAD_REGISTERS 1 /** * @brief A task is created without a secure context, and must call * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes * any secure calls. */ #define portNO_SECURE_CONTEXT 0 /*-----------------------------------------------------------*/ /** * @brief Used to catch tasks that attempt to return from their implementing * function. */ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) /** * @brief Setup the Memory Protection Unit (MPU). */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) /** * @brief Setup the Floating Point Unit (FPU). */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ /** * @brief Setup the timer to generate the tick interrupts. * * The implementation in this file is weak to allow application writers to * change the timer used to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /** * @brief Checks whether the current execution context is interrupt. * * @return pdTRUE if the current execution context is interrupt, pdFALSE * otherwise. */ BaseType_t xPortIsInsideInterrupt( void ); /** * @brief Yield the processor. */ void vPortYield( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ void vPortExitCritical( void ) PRIVILEGED_FUNCTION; /** * @brief SysTick handler. */ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; /** * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. */ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Saved as part of the task context to indicate which context the * task is using on the secure side. */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ #if ( configUSE_TICKLESS_IDLE == 1 ) /** * @brief The number of SysTick increments that make up one tick period. */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; /** * @brief The maximum number of tick periods that can be suppressed is * limited by the 24 bit resolution of the SysTick timer. */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; /** * @brief Compensate for the CPU cycles that pass while the SysTick is * stopped (low power functionality only). */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). Artificially force an assert() * to be triggered if configASSERT() is defined, then stop here so * application writers can catch the error. */ configASSERT( ulCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being * defined but never called. ulDummy is used purely to quieten other * warnings about code appearing after this function is called - making * ulDummy volatile makes the compiler think the function could return * and therefore not output an 'unreachable code' warning for code that * appears after it. */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; extern uint32_t * __unprivileged_flash_start__; extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* if defined( __ARMCC_VERSION ) */ /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; extern uint32_t __unprivileged_flash_start__[]; extern uint32_t __unprivileged_flash_end__[]; extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check that the MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* MAIR0 - Index 0. */ portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); /* MAIR0 - Index 1. */ portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* Setup privileged flash as Read Only so that privileged tasks can * read it but not modify. */ portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged flash as Read Only by both privileged and * unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged syscalls flash as Read Only by both privileged * and unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup RAM containing kernel data for privileged access only. */ portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Enable mem fault. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; /* Enable MPU with privileged background access i.e. unmapped * regions have privileged access. */ portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) { /* Enable non-secure access to the FPU. */ SecureInit_EnableNSFPUAccess(); } #endif /* configENABLE_TRUSTZONE */ /* CP10 = 11 ==> Full access to FPU i.e. both privileged and * unprivileged code should be able to access FPU. CP11 should be * programmed to the same value as CP10. */ *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) ); /* ASPEN = 1 ==> Hardware should automatically preserve floating point * context on exception entry and restore on exception return. * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ void vPortYield( void ) /* PRIVILEGED_FUNCTION */ { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ { portDISABLE_INTERRUPTS(); ulCriticalNesting++; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ { configASSERT( ulCriticalNesting ); ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { #if ( configENABLE_MPU == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ #endif /* configENABLE_MPU */ uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) uint32_t ulR0, ulR1; extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ #endif /* configENABLE_TRUSTZONE */ uint8_t ucSVCNumber; /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ ulPC = pulCallerStackAddress[ 6 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { #if ( configENABLE_TRUSTZONE == 1 ) case portSVC_ALLOCATE_SECURE_CONTEXT: /* R0 contains the stack size passed as parameter to the * vPortAllocateSecureContext function. */ ulR0 = pulCallerStackAddress[ 0 ]; #if ( configENABLE_MPU == 1 ) { /* Read the CONTROL register value. */ __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); /* The task that raised the SVC is privileged if Bit[0] * in the CONTROL register is 0. */ ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: /* R0 contains TCB being freed and R1 contains the secure * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) { /* De-prioritize the non-secure exceptions so that the * non-secure pendSV runs at the lowest priority. */ SecureInit_DePrioritizeNSExceptions(); /* Initialize the secure context management system. */ SecureContext_Init(); } #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_FPU == 1 ) { /* Setup the Floating Point Unit (FPU). */ prvSetupFPU(); } #endif /* configENABLE_FPU */ /* Setup the context of the first task so that the first task starts * executing. */ vRestoreContextOfFirstTask(); break; #if ( configENABLE_MPU == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the svc was raised from any of * the system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { vRaisePrivilege(); } break; #endif /* configENABLE_MPU */ default: /* Incorrect SVC call. */ configASSERT( pdFALSE ); } } /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #if ( configENABLE_MPU == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /* *INDENT-ON* */ { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #endif /* portPRELOAD_REGISTERS */ return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ prvSetupMPU(); } #endif /* configENABLE_MPU */ /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; /* Start the first task. */ vStartFirstTask(); /* Should never get here as the tasks will now be executing. Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* Setup MAIR0. */ xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ if( ulStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged * SRAM is already protected using an MPU region and ARMv8-M does * not allow overlapping MPU regions. */ if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) { xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; } else { /* Define the region that allows access to the stack. */ ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); } } /* User supplied configurable regions. */ for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) { /* If xRegions is NULL i.e. the task has not specified any MPU * region, the else part ensures that all the configurable MPU * regions are invalidated. */ if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) { /* Translate the generic region definition contained in xRegions * into the ARMv8 specific MPU settings that are then stored in * xMPUSettings. */ ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; /* Start address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ); /* RO/RW. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); } else { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); } /* XN. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); } /* End Address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { /* Attr1 in MAIR0 is configured as device memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; } else { /* Attr0 in MAIR0 is configured as normal memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; } } else { /* Invalidate the region. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; } lIndex++; } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. Interrupt Program * Status Register (IPSR) holds the exception number of the currently-executing * exception or zero for Thread mode.*/ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORT_ASM_H__ #define __PORT_ASM_H__ /* Scheduler includes. */ #include "FreeRTOS.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /** * @brief Restore the context of the first task so that the first task starts * executing. */ void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * * @note This is a privileged function and should only be called from the kenrel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Starts the first task. */ void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Disables interrupts. */ uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Enables interrupts. */ void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief PendSV Exception handler. */ void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief SVC Handler. */ void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Allocate a Secure context for the calling task. * * @param[in] ulSecureStackSize The size of the stack to be allocated on the * secure side for the calling task. */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); /** * @brief Free the task's secure context. * * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. */ void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* __PORT_ASM_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" EXTERN pxCurrentTCB EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C PUBLIC xIsPrivileged PUBLIC vResetPrivilege PUBLIC vRestoreContextOfFirstTask PUBLIC vRaisePrivilege PUBLIC vStartFirstTask PUBLIC ulSetInterruptMask PUBLIC vClearInterruptMask PUBLIC PendSV_Handler PUBLIC SVC_Handler /*-----------------------------------------------------------*/ /*---------------- Unprivileged Functions -------------------*/ /*-----------------------------------------------------------*/ SECTION .text:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ xIsPrivileged: mrs r0, control /* r0 = CONTROL. */ tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ ite ne movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ vResetPrivilege: mrs r0, control /* r0 = CONTROL. */ orr r0, r0, #1 /* r0 = r0 | 1. */ msr control, r0 /* CONTROL = r0. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ /*----------------- Privileged Functions --------------------*/ /*-----------------------------------------------------------*/ SECTION privileged_functions:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ str r4, [r2] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r3, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ movs r3, #4 /* r3 = 4. */ str r3, [r2] /* Program RNR = 4. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ str r4, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ msr control, r2 /* Set this task's CONTROL value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r3 /* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r2 /* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ vRaisePrivilege: mrs r0, control /* Read the CONTROL register. */ bic r0, r0, #1 /* Clear the bit 0. */ msr control, r0 /* Write back the new CONTROL value. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vStartFirstTask: ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ ldr r0, [r0] /* The first entry in vector table is stack pointer. */ msr msp, r0 /* Set the MSP back to the start of the stack. */ cpsie i /* Globally enable interrupts. */ cpsie f dsb isb svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ /*-----------------------------------------------------------*/ ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ /*-----------------------------------------------------------*/ vClearInterruptMask: msr basepri, r0 /* basepri = ulMask. */ dsb isb bx lr /* Return. */ /*-----------------------------------------------------------*/ PendSV_Handler: mrs r0, psp /* Read PSP in r0. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r0!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) mrs r1, psplim /* r1 = PSPLIM. */ mrs r2, control /* r2 = CONTROL. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r1-r11} /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ #else /* configENABLE_MPU */ mrs r2, psplim /* r2 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ #endif /* configENABLE_MPU */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ str r4, [r2] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r3, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ movs r3, #4 /* r3 = 4. */ str r3, [r2] /* Program RNR = 4. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ str r4, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldmia r0!, {r1-r11} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ #else /* configENABLE_MPU */ ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #endif /* configENABLE_MPU */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst r3, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r0!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) msr psplim, r1 /* Restore the PSPLIM register value for the task. */ msr control, r2 /* Restore the CONTROL register value for the task. */ #else /* configENABLE_MPU */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */ #endif /* configENABLE_MPU */ msr psp, r0 /* Remember the new top of stack for the task. */ bx r3 /*-----------------------------------------------------------*/ SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp b vPortSVCHandler_C /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55_NTZ/non_secure/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_MVE #error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE. #endif /* configENABLE_MVE */ /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M55" #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Be006 #pragma diag_suppress=Pa082 /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACROCOMMON_H #define PORTMACROCOMMON_H #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_FPU #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. #endif /* configENABLE_FPU */ #ifndef configENABLE_MPU #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. #endif /* configENABLE_MPU */ #ifndef configENABLE_TRUSTZONE #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ /** * @brief Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif #define portHAS_STACK_OVERFLOW_CHECKING 1 /*-----------------------------------------------------------*/ /** * @brief Extern declarations. */ extern BaseType_t xPortIsInsideInterrupt( void ); extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; #if ( configENABLE_TRUSTZONE == 1 ) extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_MPU == 1 ) extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief MPU specific constants. */ #if ( configENABLE_MPU == 1 ) #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #else #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* MPU regions. */ #define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_RAM_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ /* Device memory attributes used in MPU_MAIR registers. * * 8-bit values encoded as follows: * Bit[7:4] - 0000 - Device Memory * Bit[3:2] - 00 --> Device-nGnRnE * 01 --> Device-nGnRE * 10 --> Device-nGRE * 11 --> Device-GRE * Bit[1:0] - 00, Reserved. */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ /* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ /* Attributes used in MPU_RBAR registers. */ #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ /** * @brief Settings to define an MPU region. */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */ } MPURegionSettings_t; /** * @brief MPU settings as stored in the TCB. */ typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ } xMPU_SETTINGS; /*-----------------------------------------------------------*/ /** * @brief SVC numbers. */ #define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 /*-----------------------------------------------------------*/ /** * @brief Scheduler utilities. */ #define portYIELD() vPortYield() #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /** * @brief Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /** * @brief Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Allocate a secure context for the task. * * 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 context before it calls any secure function. * * @param[in] ulSecureStackSize The size of the secure stack to be allocated. */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) /** * @brief Called when a task is deleted to delete the task's secure context, * if it has one. * * @param[in] pxTCB The TCB of the task being deleted. */ #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. * * 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, * the privilege is not raised. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() #else #define portIS_PRIVILEGED() #define portRAISE_PRIVILEGE() #define portRESET_PRIVILEGE() #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief Barriers. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACROCOMMON_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM7/ReadMe.txt ================================================ There are two options for running FreeRTOS on ARM Cortex-M7 microcontrollers. The best option depends on the revision of the ARM Cortex-M7 core in use. The revision is specified by an 'r' number, and a 'p' number, so will look something like 'r0p1'. Check the documentation for the microcontroller in use to find the revision of the Cortex-M7 core used in that microcontroller. If in doubt, use the FreeRTOS port provided specifically for r0p1 revisions, as that can be used with all core revisions. The first option is to use the ARM Cortex-M4F port, and the second option is to use the Cortex-M7 r0p1 port - the latter containing a minor errata workaround. If the revision of the ARM Cortex-M7 core is not r0p1 then either option can be used, but it is recommended to use the FreeRTOS ARM Cortex-M4F port located in the /FreeRTOS/Source/portable/IAR/ARM_CM4F directory. If the revision of the ARM Cortex-M7 core is r0p1 then use the FreeRTOS ARM Cortex-M7 r0p1 port located in the /FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1 directory. ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM7/r0p1/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM7 port. *----------------------------------------------------------*/ /* IAR includes. */ #include /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #ifndef __ARMVFP__ #error This port can only be used when the project options are configured to enable hardware floating point support. #endif #if ( configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 ) #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ #endif /* Constants required to manipulate the core. Registers first... */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) /* ...then bits in the registers. */ #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) #define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) ) #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ #define portVECTACTIVE_MASK ( 0xFFUL ) /* Constants required to manipulate the VFP. */ #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_EXC_RETURN ( 0xfffffffd ) /* The systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /* A fiddle factor to estimate the number of SysTick counts that would have * occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) /* Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ); /* * Exception handlers. */ void xPortSysTickHandler( void ); /* * Start first task is a separate function so it can be tested in isolation. */ extern void vPortStartFirstTask( void ); /* * Turn the VFP on. */ extern void vPortEnableVFP( void ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* Each task maintains its own interrupt status in the critical nesting * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* * The number of SysTick increments that make up one tick period. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulTimerCountsForOneTick = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * The maximum number of tick periods that can be suppressed is limited by the * 24 bit resolution of the SysTick timer. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t xMaximumPossibleSuppressedTicks = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Compensate for the CPU cycles that pass while the SysTick is stopped (low * power functionality only. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. */ #if ( configASSERT_DEFINED == 1 ) static uint8_t ucMaxSysCallPriority = 0; static uint32_t ulMaxPRIGROUPValue = 0; static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ /* Offset added to account for the way the MCU uses the stack on entry/exit * of interrupts, and to ensure alignment. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */ /* Save code space by skipping register initialisation. */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ /* A save method is being used that requires each task to maintain its * own exec return value. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). * * Artificially force an assert() to be triggered if configASSERT() is * defined, then stop here so application writers can catch the error. */ configASSERT( uxCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); for( ; ; ) { } } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API * functions can be called. ISR safe functions are those that end in * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { ulMaxPRIGROUPValue--; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); } #endif /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; /* Restore the clobbered interrupt priority register to its original * value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Ensure the VFP is enabled - it should be anyway. */ vPortEnableVFP(); /* Lazy save always. */ *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; /* Start the first task. */ vPortStartFirstTask(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); uxCriticalNesting++; /* 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 * 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 * assert function also uses a critical section. */ if( uxCriticalNesting == 1 ) { configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { /* The SysTick runs at the lowest interrupt priority, so when this interrupt * executes all interrupts must be unmasked. There is therefore no need to * save and then restore the interrupt mask value as its value is already * known. */ portDISABLE_INTERRUPTS(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* A context switch is required. Context switching is performed in * the PendSV interrupt. Pend the PendSV interrupt. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portENABLE_INTERRUPTS(); } /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __weak void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __disable_interrupt(); __DSB(); __ISB(); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the __disable_interrupt() * call above. */ __enable_interrupt(); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __DSB(); __WFI(); __ISB(); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the __disable_interrupt() call above. */ __enable_interrupt(); __DSB(); __ISB(); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __disable_interrupt(); __DSB(); __ISB(); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __enable_interrupt(); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ /* * Setup the systick timer to generate the tick interrupts at the required * frequency. */ __weak void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and clear the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); } /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); /* Is the interrupt number a user defined interrupt? */ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /* Look up the interrupt's priority. */ ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Interrupts that use the FreeRTOS API must not be left at their * default priority of zero as that is the highest possible priority, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * and therefore also guaranteed to be invalid. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } /* Priority grouping: The interrupt controller (NVIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined * to be pre-emption priority bits. The following assertion will fail if * this is not the case (if some bits represent a sub-priority). * * If the application only uses CMSIS libraries for interrupt * configuration then the correct setting can be achieved on all Cortex-M * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * scheduler. Note however that some vendor specific peripheral libraries * assume a non-zero priority group setting, in which cases using a value * of zero will result in unpredictable behaviour. */ configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); } #endif /* configASSERT_DEFINED */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM7/r0p1/portasm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #include RSEG CODE:CODE(2) thumb EXTERN pxCurrentTCB EXTERN vTaskSwitchContext PUBLIC xPortPendSVHandler PUBLIC vPortSVCHandler PUBLIC vPortStartFirstTask PUBLIC vPortEnableVFP /*-----------------------------------------------------------*/ xPortPendSVHandler: mrs r0, psp isb /* Get the location of the current TCB. */ ldr r3, =pxCurrentTCB ldr r2, [r3] /* Is the task using the FPU context? If so, push high vfp registers. */ tst r14, #0x10 it eq vstmdbeq r0!, {s16-s31} /* Save the core registers. */ stmdb r0!, {r4-r11, r14} /* Save the new top of stack into the first member of the TCB. */ str r0, [r2] stmdb sp!, {r0, r3} mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY cpsid i msr basepri, r0 dsb isb cpsie i bl vTaskSwitchContext mov r0, #0 msr basepri, r0 ldmia sp!, {r0, r3} /* The first item in pxCurrentTCB is the task top of stack. */ ldr r1, [r3] ldr r0, [r1] /* Pop the core registers. */ ldmia r0!, {r4-r11, r14} /* Is the task using the FPU context? If so, pop the high vfp registers too. */ tst r14, #0x10 it eq vldmiaeq r0!, {s16-s31} msr psp, r0 isb #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */ #if WORKAROUND_PMU_CM001 == 1 push { r14 } pop { pc } #endif #endif bx r14 /*-----------------------------------------------------------*/ vPortSVCHandler: /* Get the location of the current TCB. */ ldr r3, =pxCurrentTCB ldr r1, [r3] ldr r0, [r1] /* Pop the core registers. */ ldmia r0!, {r4-r11, r14} msr psp, r0 isb mov r0, #0 msr basepri, r0 bx r14 /*-----------------------------------------------------------*/ vPortStartFirstTask /* Use the NVIC offset register to locate the stack. */ ldr r0, =0xE000ED08 ldr r0, [r0] ldr r0, [r0] /* Set the msp back to the start of the stack. */ msr msp, r0 /* Clear the bit that indicates the FPU is in use in case the FPU was used before the scheduler was started - which would otherwise result in the unnecessary leaving of space in the SVC stack for lazy saving of FPU registers. */ mov r0, #0 msr control, r0 /* Call SVC to start the first task. */ cpsie i cpsie f dsb isb svc 0 /*-----------------------------------------------------------*/ vPortEnableVFP: /* The FPU enable bits are in the CPACR. */ ldr.w r0, =0xE000ED88 ldr r1, [r0] /* Enable CP10 and CP11 coprocessors, then save back. */ orr r1, r1, #( 0xf << 20 ) str r1, [r0] bx r14 END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM7/r0p1/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* IAR includes. */ #include /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Compiler directives. */ #define portWEAK_SYMBOL __attribute__( ( weak ) ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ #define portYIELD() \ { \ /* Set a PendSV to request a context switch. */ \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ __DSB(); \ __ISB(); \ } #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 ) /* Check the configuration. */ #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. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) __CLZ( ( uxReadyPriorities ) ) ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); #define portDISABLE_INTERRUPTS() \ { \ /* Errata work around. */ \ __disable_interrupt(); \ __set_BASEPRI( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \ __DSB(); \ __ISB(); \ __enable_interrupt(); \ } #define portENABLE_INTERRUPTS() __set_BASEPRI( 0 ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() #define portSET_INTERRUPT_MASK_FROM_ISR() __get_BASEPRI(); portDISABLE_INTERRUPTS() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) __set_BASEPRI( x ) /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /* 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 * (which build with all the ports) will build. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* portNOP() is not required by this port. */ #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif /*-----------------------------------------------------------*/ portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Pe191 #pragma diag_suppress=Pa082 #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85/non_secure/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /* Portasm includes. */ #include "portasm.h" #if ( configENABLE_TRUSTZONE == 1 ) /* Secure components includes. */ #include "secure_context.h" #include "secure_init.h" #endif /* configENABLE_TRUSTZONE */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /** * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS * on the secure side. The following are the valid configuration seetings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 * * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 * * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 */ #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. #endif /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the SCB. */ #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the FPU. */ #define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) #define portMPU_RLAR_REGION_ENABLE ( 1UL ) /* Enable privileged access to unmapped region. */ #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /*-----------------------------------------------------------*/ /** * @brief The maximum 24-bit number. * * It is needed because the systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /** * @brief A fiddle factor to estimate the number of SysTick counts that would * have occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) /** * @brief Initial EXC_RETURN value. * * FF FF FF FD * 1111 1111 1111 1111 1111 1111 1111 1101 * * Bit[6] - 1 --> The exception was taken from the Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 1 --> The exception was taken to the Secure state. */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else /** * @brief Initial EXC_RETURN value. * * FF FF FF BC * 1111 1111 1111 1111 1111 1111 1011 1100 * * Bit[6] - 0 --> The exception was taken from the Non-Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 0 --> The exception was taken to the Non-Secure state. */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ /** * @brief CONTROL register privileged bit mask. * * Bit[0] in CONTROL register tells the privilege: * Bit[0] = 0 ==> The task is privileged. * Bit[0] = 1 ==> The task is not privileged. */ #define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) /** * @brief Initial CONTROL register values. */ #define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) #define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) /** * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /** * @brief 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /** * @brief If portPRELOAD_REGISTERS then registers will be given an initial value * when a task is created. This helps in debugging at the cost of code size. */ #define portPRELOAD_REGISTERS 1 /** * @brief A task is created without a secure context, and must call * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes * any secure calls. */ #define portNO_SECURE_CONTEXT 0 /*-----------------------------------------------------------*/ /** * @brief Used to catch tasks that attempt to return from their implementing * function. */ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) /** * @brief Setup the Memory Protection Unit (MPU). */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) /** * @brief Setup the Floating Point Unit (FPU). */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ /** * @brief Setup the timer to generate the tick interrupts. * * The implementation in this file is weak to allow application writers to * change the timer used to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /** * @brief Checks whether the current execution context is interrupt. * * @return pdTRUE if the current execution context is interrupt, pdFALSE * otherwise. */ BaseType_t xPortIsInsideInterrupt( void ); /** * @brief Yield the processor. */ void vPortYield( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ void vPortExitCritical( void ) PRIVILEGED_FUNCTION; /** * @brief SysTick handler. */ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; /** * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. */ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Saved as part of the task context to indicate which context the * task is using on the secure side. */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ #if ( configUSE_TICKLESS_IDLE == 1 ) /** * @brief The number of SysTick increments that make up one tick period. */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; /** * @brief The maximum number of tick periods that can be suppressed is * limited by the 24 bit resolution of the SysTick timer. */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; /** * @brief Compensate for the CPU cycles that pass while the SysTick is * stopped (low power functionality only). */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). Artificially force an assert() * to be triggered if configASSERT() is defined, then stop here so * application writers can catch the error. */ configASSERT( ulCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being * defined but never called. ulDummy is used purely to quieten other * warnings about code appearing after this function is called - making * ulDummy volatile makes the compiler think the function could return * and therefore not output an 'unreachable code' warning for code that * appears after it. */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; extern uint32_t * __unprivileged_flash_start__; extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* if defined( __ARMCC_VERSION ) */ /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; extern uint32_t __unprivileged_flash_start__[]; extern uint32_t __unprivileged_flash_end__[]; extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check that the MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* MAIR0 - Index 0. */ portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); /* MAIR0 - Index 1. */ portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* Setup privileged flash as Read Only so that privileged tasks can * read it but not modify. */ portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged flash as Read Only by both privileged and * unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged syscalls flash as Read Only by both privileged * and unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup RAM containing kernel data for privileged access only. */ portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Enable mem fault. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; /* Enable MPU with privileged background access i.e. unmapped * regions have privileged access. */ portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) { /* Enable non-secure access to the FPU. */ SecureInit_EnableNSFPUAccess(); } #endif /* configENABLE_TRUSTZONE */ /* CP10 = 11 ==> Full access to FPU i.e. both privileged and * unprivileged code should be able to access FPU. CP11 should be * programmed to the same value as CP10. */ *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) ); /* ASPEN = 1 ==> Hardware should automatically preserve floating point * context on exception entry and restore on exception return. * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ void vPortYield( void ) /* PRIVILEGED_FUNCTION */ { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ { portDISABLE_INTERRUPTS(); ulCriticalNesting++; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ { configASSERT( ulCriticalNesting ); ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { #if ( configENABLE_MPU == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ #endif /* configENABLE_MPU */ uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) uint32_t ulR0, ulR1; extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ #endif /* configENABLE_TRUSTZONE */ uint8_t ucSVCNumber; /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ ulPC = pulCallerStackAddress[ 6 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { #if ( configENABLE_TRUSTZONE == 1 ) case portSVC_ALLOCATE_SECURE_CONTEXT: /* R0 contains the stack size passed as parameter to the * vPortAllocateSecureContext function. */ ulR0 = pulCallerStackAddress[ 0 ]; #if ( configENABLE_MPU == 1 ) { /* Read the CONTROL register value. */ __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); /* The task that raised the SVC is privileged if Bit[0] * in the CONTROL register is 0. */ ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: /* R0 contains TCB being freed and R1 contains the secure * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) { /* De-prioritize the non-secure exceptions so that the * non-secure pendSV runs at the lowest priority. */ SecureInit_DePrioritizeNSExceptions(); /* Initialize the secure context management system. */ SecureContext_Init(); } #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_FPU == 1 ) { /* Setup the Floating Point Unit (FPU). */ prvSetupFPU(); } #endif /* configENABLE_FPU */ /* Setup the context of the first task so that the first task starts * executing. */ vRestoreContextOfFirstTask(); break; #if ( configENABLE_MPU == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the svc was raised from any of * the system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { vRaisePrivilege(); } break; #endif /* configENABLE_MPU */ default: /* Incorrect SVC call. */ configASSERT( pdFALSE ); } } /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #if ( configENABLE_MPU == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /* *INDENT-ON* */ { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #endif /* portPRELOAD_REGISTERS */ return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ prvSetupMPU(); } #endif /* configENABLE_MPU */ /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; /* Start the first task. */ vStartFirstTask(); /* Should never get here as the tasks will now be executing. Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* Setup MAIR0. */ xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ if( ulStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged * SRAM is already protected using an MPU region and ARMv8-M does * not allow overlapping MPU regions. */ if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) { xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; } else { /* Define the region that allows access to the stack. */ ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); } } /* User supplied configurable regions. */ for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) { /* If xRegions is NULL i.e. the task has not specified any MPU * region, the else part ensures that all the configurable MPU * regions are invalidated. */ if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) { /* Translate the generic region definition contained in xRegions * into the ARMv8 specific MPU settings that are then stored in * xMPUSettings. */ ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; /* Start address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ); /* RO/RW. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); } else { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); } /* XN. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); } /* End Address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { /* Attr1 in MAIR0 is configured as device memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; } else { /* Attr0 in MAIR0 is configured as normal memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; } } else { /* Invalidate the region. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; } lIndex++; } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. Interrupt Program * Status Register (IPSR) holds the exception number of the currently-executing * exception or zero for Thread mode.*/ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85/non_secure/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORT_ASM_H__ #define __PORT_ASM_H__ /* Scheduler includes. */ #include "FreeRTOS.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /** * @brief Restore the context of the first task so that the first task starts * executing. */ void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * * @note This is a privileged function and should only be called from the kenrel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Starts the first task. */ void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Disables interrupts. */ uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Enables interrupts. */ void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief PendSV Exception handler. */ void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief SVC Handler. */ void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Allocate a Secure context for the calling task. * * @param[in] ulSecureStackSize The size of the stack to be allocated on the * secure side for the calling task. */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); /** * @brief Free the task's secure context. * * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. */ void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* __PORT_ASM_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85/non_secure/portasm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C EXTERN SecureContext_SaveContext EXTERN SecureContext_LoadContext PUBLIC xIsPrivileged PUBLIC vResetPrivilege PUBLIC vPortAllocateSecureContext PUBLIC vRestoreContextOfFirstTask PUBLIC vRaisePrivilege PUBLIC vStartFirstTask PUBLIC ulSetInterruptMask PUBLIC vClearInterruptMask PUBLIC PendSV_Handler PUBLIC SVC_Handler PUBLIC vPortFreeSecureContext /*-----------------------------------------------------------*/ /*---------------- Unprivileged Functions -------------------*/ /*-----------------------------------------------------------*/ SECTION .text:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ xIsPrivileged: mrs r0, control /* r0 = CONTROL. */ tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ ite ne movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ vResetPrivilege: mrs r0, control /* r0 = CONTROL. */ orr r0, r0, #1 /* r0 = r0 | 1. */ msr control, r0 /* CONTROL = r0. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vPortAllocateSecureContext: svc 0 /* Secure context is allocated in the supervisor call. portSVC_ALLOCATE_SECURE_CONTEXT = 0. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ /*----------------- Privileged Functions --------------------*/ /*-----------------------------------------------------------*/ SECTION privileged_functions:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ str r4, [r2] /* Disable MPU. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r4, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ movs r4, #4 /* r4 = 4. */ str r4, [r2] /* Program RNR = 4. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldmia r3!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ str r4, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ ldr r5, =xSecureContext str r1, [r5] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ msr control, r3 /* Set this task's CONTROL value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r4 /* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r3 /* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ vRaisePrivilege: mrs r0, control /* Read the CONTROL register. */ bic r0, r0, #1 /* Clear the bit 0. */ msr control, r0 /* Write back the new CONTROL value. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vStartFirstTask: ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ ldr r0, [r0] /* The first entry in vector table is stack pointer. */ msr msp, r0 /* Set the MSP back to the start of the stack. */ cpsie i /* Globally enable interrupts. */ cpsie f dsb isb svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ /*-----------------------------------------------------------*/ ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ /*-----------------------------------------------------------*/ vClearInterruptMask: msr basepri, r0 /* basepri = ulMask. */ dsb isb bx lr /* Return. */ /*-----------------------------------------------------------*/ PendSV_Handler: ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ push {r0-r2, r14} bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r0-r3} /* LR is now in r3. */ mov lr, r3 /* LR = r3. */ lsls r1, r3, #25 /* 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 /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ b select_next_task save_ns_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ adds r2, r2, #16 /* r2 = r2 + 16. */ stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ subs r2, r2, #16 /* r2 = r2 - 16. */ stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ adds r2, r2, #12 /* r2 = r2 + 12. */ stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ subs r2, r2, #12 /* r2 = r2 - 12. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r3] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ str r4, [r3] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ str r4, [r3] /* Program MAIR0. */ ldr r3, =0xe000ed98 /* r3 = 0xe000ed98 [Location of RNR]. */ movs r4, #4 /* r4 = 4. */ str r4, [r3] /* Program RNR = 4. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ stmia r3!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r3] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ str r4, [r3] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ msr control, r3 /* Restore the CONTROL register value for the task. */ mov lr, r4 /* LR = r4. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ push {r2, r4} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r2, r4} mov lr, r4 /* LR = r4. */ lsls r1, r4, #25 /* 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 /* 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 /* Remember the new top of stack for the task. */ bx lr #else /* configENABLE_MPU */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ push {r2, r4} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r2, r4} mov lr, r4 /* LR = r4. */ lsls r1, r4, #25 /* 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 /* 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 /* Remember the new top of stack for the task. */ bx lr #endif /* configENABLE_MPU */ restore_ns_context: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ msr psp, r2 /* Remember the new top of stack for the task. */ bx lr /*-----------------------------------------------------------*/ SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp b vPortSVCHandler_C /*-----------------------------------------------------------*/ vPortFreeSecureContext: /* r0 = uint32_t *pulTCB. */ ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ it ne svcne 1 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 1. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85/non_secure/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_MVE #error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE. #endif /* configENABLE_MVE */ /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M85" #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Be006 #pragma diag_suppress=Pa082 /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACROCOMMON_H #define PORTMACROCOMMON_H #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_FPU #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. #endif /* configENABLE_FPU */ #ifndef configENABLE_MPU #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. #endif /* configENABLE_MPU */ #ifndef configENABLE_TRUSTZONE #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ /** * @brief Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif #define portHAS_STACK_OVERFLOW_CHECKING 1 /*-----------------------------------------------------------*/ /** * @brief Extern declarations. */ extern BaseType_t xPortIsInsideInterrupt( void ); extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; #if ( configENABLE_TRUSTZONE == 1 ) extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_MPU == 1 ) extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief MPU specific constants. */ #if ( configENABLE_MPU == 1 ) #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #else #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* MPU regions. */ #define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_RAM_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ /* Device memory attributes used in MPU_MAIR registers. * * 8-bit values encoded as follows: * Bit[7:4] - 0000 - Device Memory * Bit[3:2] - 00 --> Device-nGnRnE * 01 --> Device-nGnRE * 10 --> Device-nGRE * 11 --> Device-GRE * Bit[1:0] - 00, Reserved. */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ /* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ /* Attributes used in MPU_RBAR registers. */ #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ /** * @brief Settings to define an MPU region. */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */ } MPURegionSettings_t; /** * @brief MPU settings as stored in the TCB. */ typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ } xMPU_SETTINGS; /*-----------------------------------------------------------*/ /** * @brief SVC numbers. */ #define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 /*-----------------------------------------------------------*/ /** * @brief Scheduler utilities. */ #define portYIELD() vPortYield() #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /** * @brief Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /** * @brief Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Allocate a secure context for the task. * * 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 context before it calls any secure function. * * @param[in] ulSecureStackSize The size of the secure stack to be allocated. */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) /** * @brief Called when a task is deleted to delete the task's secure context, * if it has one. * * @param[in] pxTCB The TCB of the task being deleted. */ #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. * * 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, * the privilege is not raised. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() #else #define portIS_PRIVILEGED() #define portRAISE_PRIVILEGE() #define portRESET_PRIVILEGE() #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief Barriers. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACROCOMMON_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85/secure/secure_context.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Secure context includes. */ #include "secure_context.h" /* Secure heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief CONTROL value for privileged tasks. * * Bit[0] - 0 --> Thread mode is privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_PRIVILEGED 0x02 /** * @brief CONTROL value for un-privileged tasks. * * Bit[0] - 1 --> Thread mode is un-privileged. * Bit[1] - 1 --> Thread mode uses PSP. */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 /** * @brief Size of stack seal values in bytes. */ #define securecontextSTACK_SEAL_SIZE 8 /** * @brief Stack seal value as recommended by ARM. */ #define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5 /** * @brief Maximum number of secure contexts. */ #ifndef secureconfigMAX_SECURE_CONTEXTS #define secureconfigMAX_SECURE_CONTEXTS 8UL #endif /*-----------------------------------------------------------*/ /** * @brief Pre-allocated array of secure contexts. */ SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ]; /*-----------------------------------------------------------*/ /** * @brief Get a free secure context for a task from the secure context pool (xSecureContexts). * * This function ensures that only one secure context is allocated for a task. * * @param[in] pvTaskHandle The task handle for which the secure context is allocated. * * @return Index of a free secure context in the xSecureContexts array. */ static uint32_t ulGetSecureContext( void * pvTaskHandle ); /** * @brief Return the secure context to the secure context pool (xSecureContexts). * * @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array. */ static void vReturnSecureContext( uint32_t ulSecureContextIndex ); /* These are implemented in assembly. */ extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ); extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ); /*-----------------------------------------------------------*/ static uint32_t ulGetSecureContext( void * pvTaskHandle ) { /* Start with invalid index. */ uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) && ( xSecureContexts[ i ].pucStackLimit == NULL ) && ( xSecureContexts[ i ].pucStackStart == NULL ) && ( xSecureContexts[ i ].pvTaskHandle == NULL ) && ( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = i; } else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle ) { /* A task can only have one secure context. Do not allocate a second * context for the same task. */ ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; break; } } return ulSecureContextIndex; } /*-----------------------------------------------------------*/ static void vReturnSecureContext( uint32_t ulSecureContextIndex ) { xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) { uint32_t ulIPSR, i; static uint32_t ulSecureContextsInitialized = 0; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) ) { /* Ensure to initialize secure contexts only once. */ ulSecureContextsInitialized = 1; /* No stack for thread mode until a task's context is loaded. */ secureportSET_PSPLIM( securecontextNO_STACK ); secureportSET_PSP( securecontextNO_STACK ); /* Initialize all secure contexts. */ for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { xSecureContexts[ i ].pucCurrentStackPointer = NULL; xSecureContexts[ i ].pucStackLimit = NULL; xSecureContexts[ i ].pucStackStart = NULL; xSecureContexts[ i ].pvTaskHandle = NULL; } #if ( configENABLE_MPU == 1 ) { /* Configure thread mode to use PSP and to be unprivileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED ); } #else /* configENABLE_MPU */ { /* Configure thread mode to use PSP and to be privileged. */ secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED ); } #endif /* configENABLE_MPU */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ) #else /* configENABLE_MPU */ secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ) #endif /* configENABLE_MPU */ { uint8_t * pucStackMemory = NULL; uint8_t * pucStackLimit; uint32_t ulIPSR, ulSecureContextIndex; SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID; #if ( configENABLE_MPU == 1 ) uint32_t * pulCurrentStackPointer = NULL; #endif /* configENABLE_MPU */ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit * Register (PSPLIM) value. */ secureportREAD_IPSR( ulIPSR ); secureportREAD_PSPLIM( pucStackLimit ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. * Also do nothing, if a secure context us already loaded. PSPLIM is set to * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { /* Ontain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space. */ pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE ); if( pucStackMemory != NULL ) { /* Since stack grows down, the starting point will be the last * location. Note that this location is next to the last * allocated byte for stack (excluding the space for seal values) * because the hardware decrements the stack pointer before * writing i.e. if stack pointer is 0x2, a push operation will * decrement the stack pointer to 0x1 and then write at 0x1. */ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize; /* Seal the created secure process stack. */ *( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE; *( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE; /* The stack cannot go beyond this location. This value is * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle; #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 ) { *( 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 /* configENABLE_MPU */ { /* Current SP is set to the starting of the stack. This * value programmed in the PSP register on context switch. */ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart; } #endif /* configENABLE_MPU */ /* Ensure to never return 0 as a valid context handle. */ xSecureContextHandle = ulSecureContextIndex + 1UL; } } } return xSecureContextHandle; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint32_t ulIPSR, ulSecureContextIndex; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* Only free if a valid context handle is passed. */ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; /* Ensure that the secure context being deleted is associated with * the task. */ if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) { /* Free the stack space. */ vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); /* Return the secure context back to the free secure contexts pool. */ vReturnSecureContext( ulSecureContextIndex ); } } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that no secure context is loaded and the task is loading it's * own context. */ if( ( pucStackLimit == securecontextNO_STACK ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; secureportREAD_PSPLIM( pucStackLimit ); /* Ensure that task's context is loaded and the task is saving it's own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) { SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); } } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85/secure/secure_context.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_CONTEXT_H__ #define __SECURE_CONTEXT_H__ /* Standard includes. */ #include /* FreeRTOS includes. */ #include "FreeRTOSConfig.h" /** * @brief PSP value when no secure context is loaded. */ #define securecontextNO_STACK 0x0 /** * @brief Invalid context ID. */ #define securecontextINVALID_CONTEXT_ID 0UL /*-----------------------------------------------------------*/ /** * @brief Structure to represent a secure context. * * @note Since stack grows down, pucStackStart is the highest address while * pucStackLimit is the first address of the allocated memory. */ typedef struct SecureContext { uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */ uint8_t * pucStackStart; /**< First location of the stack memory. */ void * pvTaskHandle; /**< Task handle of the task this context is associated with. */ } SecureContext_t; /*-----------------------------------------------------------*/ /** * @brief Opaque handle for a secure context. */ typedef uint32_t SecureContextHandle_t; /*-----------------------------------------------------------*/ /** * @brief Initializes the secure context management system. * * PSP is set to NULL and therefore a task must allocate and load a context * before calling any secure side function in the thread mode. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureContext_Init( void ); /** * @brief Allocates a context on the secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] ulSecureStackSize Size of the stack to allocate on secure side. * @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise. * * @return Opaque context handle if context is successfully allocated, NULL * otherwise. */ #if ( configENABLE_MPU == 1 ) SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged, void * pvTaskHandle ); #else /* configENABLE_MPU */ SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, void * pvTaskHandle ); #endif /* configENABLE_MPU */ /** * @brief Frees the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the * context to be freed. */ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Loads the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be loaded. */ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Saves the given context. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. * * @param[in] xSecureContextHandle Context handle corresponding to the context * to be saved. */ void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); #endif /* __SECURE_CONTEXT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85/secure/secure_context_port_asm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ SECTION .text:CODE:NOROOT(2) THUMB /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" PUBLIC SecureContext_LoadContextAsm PUBLIC SecureContext_SaveContextAsm /*-----------------------------------------------------------*/ SecureContext_LoadContextAsm: /* pxSecureContext value is in r0. */ mrs r1, ipsr /* r1 = IPSR. */ cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ ldmia r0!, {r1, r2} /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */ #if ( configENABLE_MPU == 1 ) ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */ msr control, r3 /* CONTROL = r3. */ #endif /* configENABLE_MPU */ msr psplim, r2 /* PSPLIM = r2. */ msr psp, r1 /* PSP = r1. */ load_ctx_therad_mode: bx lr /*-----------------------------------------------------------*/ SecureContext_SaveContextAsm: /* pxSecureContext value is in r0. */ mrs r1, ipsr /* r1 = IPSR. */ cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ mrs r1, psp /* r1 = PSP. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) vstmdb r1!, {s0} /* Trigger the deferred stacking of FPU registers. */ vldmia r1!, {s0} /* Nullify the effect of the previous statement. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) mrs r2, control /* r2 = CONTROL. */ stmdb r1!, {r2} /* Store CONTROL value on the stack. */ #endif /* configENABLE_MPU */ str r1, [r0] /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */ movs r1, #0 /* r1 = securecontextNO_STACK. */ msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */ msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */ save_ctx_therad_mode: bx lr /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85/secure/secure_heap.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure context heap includes. */ #include "secure_heap.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Total heap size. */ #ifndef secureconfigTOTAL_HEAP_SIZE #define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) ) #endif /* No test marker by default. */ #ifndef mtCOVERAGE_TEST_MARKER #define mtCOVERAGE_TEST_MARKER() #endif /* No tracing by default. */ #ifndef traceMALLOC #define traceMALLOC( pvReturn, xWantedSize ) #endif /* No tracing by default. */ #ifndef traceFREE #define traceFREE( pv, xBlockSize ) #endif /* Block sizes must not get too small. */ #define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) /* Assumes 8bit bytes! */ #define secureheapBITS_PER_BYTE ( ( size_t ) 8 ) /*-----------------------------------------------------------*/ /* Allocate the memory for the heap. */ #if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) /* The application writer has already defined the array used for the RTOS * heap - probably so it can be placed in a special segment or address. */ extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #else /* configAPPLICATION_ALLOCATED_HEAP */ static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; #endif /* configAPPLICATION_ALLOCATED_HEAP */ /** * @brief The linked list structure. * * This is used to link free blocks in order of their memory address. */ typedef struct A_BLOCK_LINK { struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */ size_t xBlockSize; /**< The size of the free block. */ } BlockLink_t; /*-----------------------------------------------------------*/ /** * @brief Called automatically to setup the required heap structures the first * time pvPortMalloc() is called. */ static void prvHeapInit( void ); /** * @brief Inserts a block of memory that is being freed into the correct * position in the list of free memory blocks. * * The block being freed will be merged with the block in front it and/or the * block behind it if the memory blocks are adjacent to each other. * * @param[in] pxBlockToInsert The block being freed. */ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ); /*-----------------------------------------------------------*/ /** * @brief The size of the structure placed at the beginning of each allocated * memory block must by correctly byte aligned. */ static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); /** * @brief Create a couple of list links to mark the start and end of the list. */ static BlockLink_t xStart; static BlockLink_t * pxEnd = NULL; /** * @brief Keeps track of the number of free bytes remaining, but says nothing * about fragmentation. */ static size_t xFreeBytesRemaining = 0U; static size_t xMinimumEverFreeBytesRemaining = 0U; /** * @brief Gets set to the top bit of an size_t type. * * When this bit in the xBlockSize member of an BlockLink_t structure is set * then the block belongs to the application. When the bit is free the block is * still part of the free heap space. */ static size_t xBlockAllocatedBit = 0; /*-----------------------------------------------------------*/ static void prvHeapInit( void ) { BlockLink_t * pxFirstFreeBlock; uint8_t * pucAlignedHeap; size_t uxAddress; size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE; /* Ensure the heap starts on a correctly aligned boundary. */ uxAddress = ( size_t ) ucHeap; if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 ) { uxAddress += ( secureportBYTE_ALIGNMENT - 1 ); uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; } pucAlignedHeap = ( uint8_t * ) uxAddress; /* xStart is used to hold a pointer to the first item in the list of free * blocks. The void cast is used to prevent compiler warnings. */ xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; xStart.xBlockSize = ( size_t ) 0; /* pxEnd is used to mark the end of the list of free blocks and is inserted * at the end of the heap space. */ uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; uxAddress -= xHeapStructSize; uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); pxEnd = ( void * ) uxAddress; pxEnd->xBlockSize = 0; pxEnd->pxNextFreeBlock = NULL; /* To start with there is a single free block that is sized to take up the * entire heap space, minus the space taken by pxEnd. */ pxFirstFreeBlock = ( void * ) pucAlignedHeap; pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; pxFirstFreeBlock->pxNextFreeBlock = pxEnd; /* Only one block exists - and it covers the entire usable heap space. */ xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; /* Work out the position of the top bit in a size_t variable. */ xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 ); } /*-----------------------------------------------------------*/ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) { BlockLink_t * pxIterator; uint8_t * puc; /* Iterate through the list until a block is found that has a higher address * than the block being inserted. */ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) { /* Nothing to do here, just iterate to the right position. */ } /* Do the block being inserted, and the block it is being inserted after * make a contiguous block of memory? */ puc = ( uint8_t * ) pxIterator; if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) { pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; pxBlockToInsert = pxIterator; } else { mtCOVERAGE_TEST_MARKER(); } /* Do the block being inserted, and the block it is being inserted before * make a contiguous block of memory? */ puc = ( uint8_t * ) pxBlockToInsert; if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) { if( pxIterator->pxNextFreeBlock != pxEnd ) { /* Form one big block from the two blocks. */ pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; } else { pxBlockToInsert->pxNextFreeBlock = pxEnd; } } else { pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } /* If the block being inserted plugged a gab, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ if( pxIterator != pxBlockToInsert ) { pxIterator->pxNextFreeBlock = pxBlockToInsert; } else { mtCOVERAGE_TEST_MARKER(); } } /*-----------------------------------------------------------*/ void * pvPortMalloc( size_t xWantedSize ) { BlockLink_t * pxBlock; BlockLink_t * pxPreviousBlock; BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ if( pxEnd == NULL ) { prvHeapInit(); } else { mtCOVERAGE_TEST_MARKER(); } /* Check the requested block size is not so large that the top bit is set. * The top bit of the block size member of the BlockLink_t structure is used * to determine who owns the block - the application or the kernel, so it * must be free. */ if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) { /* The wanted size is increased so it can contain a BlockLink_t * structure in addition to the requested amount of bytes. */ if( xWantedSize > 0 ) { xWantedSize += xHeapStructSize; /* Ensure that blocks are always aligned to the required number of * bytes. */ if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 ) { /* Byte alignment required. */ xWantedSize += ( secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) ); secureportASSERT( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) == 0 ); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) { /* Traverse the list from the start (lowest address) block until * one of adequate size is found. */ pxPreviousBlock = &xStart; pxBlock = xStart.pxNextFreeBlock; while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) { pxPreviousBlock = pxBlock; pxBlock = pxBlock->pxNextFreeBlock; } /* If the end marker was reached then a block of adequate size was * not found. */ if( pxBlock != pxEnd ) { /* Return the memory space pointed to - jumping over the * BlockLink_t structure at its start. */ pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); /* This block is being returned for use so must be taken out * of the list of free blocks. */ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; /* If the block is larger than required it can be split into * two. */ if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE ) { /* This block is to be split into two. Create a new * block following the number of bytes requested. The void * cast is used to prevent byte alignment warnings from the * compiler. */ pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 ); /* Calculate the sizes of two blocks split from the single * block. */ pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; pxBlock->xBlockSize = xWantedSize; /* Insert the new block into the list of free blocks. */ prvInsertBlockIntoFreeList( pxNewBlockLink ); } else { mtCOVERAGE_TEST_MARKER(); } xFreeBytesRemaining -= pxBlock->xBlockSize; if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) { xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; } else { mtCOVERAGE_TEST_MARKER(); } /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ pxBlock->xBlockSize |= xBlockAllocatedBit; pxBlock->pxNextFreeBlock = NULL; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } traceMALLOC( pvReturn, xWantedSize ); #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { extern void vApplicationMallocFailedHook( void ); vApplicationMallocFailedHook(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */ secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 ); return pvReturn; } /*-----------------------------------------------------------*/ void vPortFree( void * pv ) { uint8_t * puc = ( uint8_t * ) pv; BlockLink_t * pxLink; if( pv != NULL ) { /* The memory being freed will have an BlockLink_t structure immediately * before it. */ puc -= xHeapStructSize; /* This casting is to keep the compiler from issuing warnings. */ pxLink = ( void * ) puc; /* Check the block is actually allocated. */ secureportASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); secureportASSERT( pxLink->pxNextFreeBlock == NULL ); if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) { if( pxLink->pxNextFreeBlock == NULL ) { /* The block is being returned to the heap - it is no longer * allocated. */ pxLink->xBlockSize &= ~xBlockAllocatedBit; secureportDISABLE_NON_SECURE_INTERRUPTS(); { /* Add this block to the list of free blocks. */ xFreeBytesRemaining += pxLink->xBlockSize; traceFREE( pv, pxLink->xBlockSize ); prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); } secureportENABLE_NON_SECURE_INTERRUPTS(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } } /*-----------------------------------------------------------*/ size_t xPortGetFreeHeapSize( void ) { return xFreeBytesRemaining; } /*-----------------------------------------------------------*/ size_t xPortGetMinimumEverFreeHeapSize( void ) { return xMinimumEverFreeBytesRemaining; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85/secure/secure_heap.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_HEAP_H__ #define __SECURE_HEAP_H__ /* Standard includes. */ #include /** * @brief Allocates memory from heap. * * @param[in] xWantedSize The size of the memory to be allocated. * * @return Pointer to the memory region if the allocation is successful, NULL * otherwise. */ void * pvPortMalloc( size_t xWantedSize ); /** * @brief Frees the previously allocated memory. * * @param[in] pv Pointer to the memory to be freed. */ void vPortFree( void * pv ); /** * @brief Get the free heap size. * * @return Free heap size. */ size_t xPortGetFreeHeapSize( void ); /** * @brief Get the minimum ever free heap size. * * @return Minimum ever free heap size. */ size_t xPortGetMinimumEverFreeHeapSize( void ); #endif /* __SECURE_HEAP_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85/secure/secure_init.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Secure init includes. */ #include "secure_init.h" /* Secure port macros. */ #include "secure_port_macros.h" /** * @brief Constants required to manipulate the SCB. */ #define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */ #define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL ) #define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS ) #define secureinitSCB_AIRCR_PRIS_POS ( 14UL ) #define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS ) /** * @brief Constants required to manipulate the FPU. */ #define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define secureinitFPCCR_LSPENS_POS ( 29UL ) #define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS ) #define secureinitFPCCR_TS_POS ( 26UL ) #define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS ) #define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */ #define secureinitNSACR_CP10_POS ( 10UL ) #define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS ) #define secureinitNSACR_CP11_POS ( 11UL ) #define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS ) /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { *( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) | ( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) | ( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK ); } } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void ) { uint32_t ulIPSR; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ if( ulIPSR != 0 ) { /* CP10 = 1 ==> Non-secure access to the Floating Point Unit is * permitted. CP11 should be programmed to the same value as CP10. */ *( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK ); /* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures * that we can enable/disable lazy stacking in port.c file. */ *( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK ); /* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP * registers (S16-S31) are also pushed to stack on exception entry and * restored on exception return. */ *( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK ); } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85/secure/secure_init.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_INIT_H__ #define __SECURE_INIT_H__ /** * @brief De-prioritizes the non-secure exceptions. * * This is needed to ensure that the non-secure PendSV runs at the lowest * priority. Context switch is done in the non-secure PendSV handler. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_DePrioritizeNSExceptions( void ); /** * @brief Sets up the Floating Point Unit (FPU) for Non-Secure access. * * Also sets FPCCR.TS=1 to ensure that the content of the Floating Point * Registers are not leaked to the non-secure side. * * @note This function must be called in the handler mode. It is no-op if called * in the thread mode. */ void SecureInit_EnableNSFPUAccess( void ); #endif /* __SECURE_INIT_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85/secure/secure_port_macros.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __SECURE_PORT_MACROS_H__ #define __SECURE_PORT_MACROS_H__ /** * @brief Byte alignment requirements. */ #define secureportBYTE_ALIGNMENT 8 #define secureportBYTE_ALIGNMENT_MASK ( 0x0007 ) /** * @brief Macro to declare a function as non-secure callable. */ #if defined( __IAR_SYSTEMS_ICC__ ) #define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root #else #define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) ) #endif /** * @brief Set the secure PRIMASK value. */ #define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Set the non-secure PRIMASK value. */ #define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \ __asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" ) /** * @brief Read the PSP value in the given variable. */ #define secureportREAD_PSP( pucOutCurrentStackPointer ) \ __asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) ) /** * @brief Set the PSP to the given value. */ #define secureportSET_PSP( pucCurrentStackPointer ) \ __asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) ) /** * @brief Read the PSPLIM value in the given variable. */ #define secureportREAD_PSPLIM( pucOutStackLimit ) \ __asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) ) /** * @brief Set the PSPLIM to the given value. */ #define secureportSET_PSPLIM( pucStackLimit ) \ __asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) ) /** * @brief Set the NonSecure MSP to the given value. */ #define secureportSET_MSP_NS( pucMainStackPointer ) \ __asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) ) /** * @brief Set the CONTROL register to the given value. */ #define secureportSET_CONTROL( ulControl ) \ __asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" ) /** * @brief Read the Interrupt Program Status Register (IPSR) value in the given * variable. */ #define secureportREAD_IPSR( ulIPSR ) \ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) ) /** * @brief PRIMASK value to enable interrupts. */ #define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0 /** * @brief PRIMASK value to disable interrupts. */ #define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1 /** * @brief Disable secure interrupts. */ #define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Disable non-secure interrupts. * * This effectively disables context switches. */ #define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) /** * @brief Enable non-secure interrupts. */ #define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL ) /** * @brief Assert definition. */ #define secureportASSERT( x ) \ if( ( x ) == 0 ) \ { \ secureportDISABLE_SECURE_INTERRUPTS(); \ secureportDISABLE_NON_SECURE_INTERRUPTS(); \ for( ; ; ) {; } \ } #endif /* __SECURE_PORT_MACROS_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85_NTZ/non_secure/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /* Portasm includes. */ #include "portasm.h" #if ( configENABLE_TRUSTZONE == 1 ) /* Secure components includes. */ #include "secure_context.h" #include "secure_init.h" #endif /* configENABLE_TRUSTZONE */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /** * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS * on the secure side. The following are the valid configuration seetings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 * * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 * * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 */ #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. #endif /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the SCB. */ #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the FPU. */ #define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ /** * @brief Constants required to manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) #define portMPU_RLAR_REGION_ENABLE ( 1UL ) /* Enable privileged access to unmapped region. */ #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /*-----------------------------------------------------------*/ /** * @brief The maximum 24-bit number. * * It is needed because the systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /** * @brief A fiddle factor to estimate the number of SysTick counts that would * have occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /*-----------------------------------------------------------*/ /** * @brief Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) /** * @brief Initial EXC_RETURN value. * * FF FF FF FD * 1111 1111 1111 1111 1111 1111 1111 1101 * * Bit[6] - 1 --> The exception was taken from the Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 1 --> The exception was taken to the Secure state. */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else /** * @brief Initial EXC_RETURN value. * * FF FF FF BC * 1111 1111 1111 1111 1111 1111 1011 1100 * * Bit[6] - 0 --> The exception was taken from the Non-Secure state. * Bit[5] - 1 --> Do not skip stacking of additional state context. * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. * Bit[3] - 1 --> Return to the Thread mode. * Bit[2] - 1 --> Restore registers from the process stack. * Bit[1] - 0 --> Reserved, 0. * Bit[0] - 0 --> The exception was taken to the Non-Secure state. */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ /** * @brief CONTROL register privileged bit mask. * * Bit[0] in CONTROL register tells the privilege: * Bit[0] = 0 ==> The task is privileged. * Bit[0] = 1 ==> The task is not privileged. */ #define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) /** * @brief Initial CONTROL register values. */ #define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) #define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) /** * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /** * @brief 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /** * @brief If portPRELOAD_REGISTERS then registers will be given an initial value * when a task is created. This helps in debugging at the cost of code size. */ #define portPRELOAD_REGISTERS 1 /** * @brief A task is created without a secure context, and must call * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes * any secure calls. */ #define portNO_SECURE_CONTEXT 0 /*-----------------------------------------------------------*/ /** * @brief Used to catch tasks that attempt to return from their implementing * function. */ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) /** * @brief Setup the Memory Protection Unit (MPU). */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) /** * @brief Setup the Floating Point Unit (FPU). */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ /** * @brief Setup the timer to generate the tick interrupts. * * The implementation in this file is weak to allow application writers to * change the timer used to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /** * @brief Checks whether the current execution context is interrupt. * * @return pdTRUE if the current execution context is interrupt, pdFALSE * otherwise. */ BaseType_t xPortIsInsideInterrupt( void ); /** * @brief Yield the processor. */ void vPortYield( void ) PRIVILEGED_FUNCTION; /** * @brief Enter critical section. */ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; /** * @brief Exit from critical section. */ void vPortExitCritical( void ) PRIVILEGED_FUNCTION; /** * @brief SysTick handler. */ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; /** * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. */ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Saved as part of the task context to indicate which context the * task is using on the secure side. */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ #if ( configUSE_TICKLESS_IDLE == 1 ) /** * @brief The number of SysTick increments that make up one tick period. */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; /** * @brief The maximum number of tick periods that can be suppressed is * limited by the 24 bit resolution of the SysTick timer. */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; /** * @brief Compensate for the CPU cycles that pass while the SysTick is * stopped (low power functionality only). */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the cpsid instruction * above. */ __asm volatile ( "cpsie i" ::: "memory" ); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "wfi" ); __asm volatile ( "isb" ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the cpsid instruction above. */ __asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "dsb" ); __asm volatile ( "isb" ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __asm volatile ( "cpsie i" ::: "memory" ); } } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { volatile uint32_t ulDummy = 0UL; /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). Artificially force an assert() * to be triggered if configASSERT() is defined, then stop here so * application writers can catch the error. */ configASSERT( ulCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); while( ulDummy == 0 ) { /* This file calls prvTaskExitError() after the scheduler has been * started to remove a compiler warning about the function being * defined but never called. ulDummy is used purely to quieten other * warnings about code appearing after this function is called - making * ulDummy volatile makes the compiler think the function could return * and therefore not output an 'unreachable code' warning for code that * appears after it. */ } } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; extern uint32_t * __unprivileged_flash_start__; extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* if defined( __ARMCC_VERSION ) */ /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; extern uint32_t __unprivileged_flash_start__[]; extern uint32_t __unprivileged_flash_end__[]; extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check that the MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* MAIR0 - Index 0. */ portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); /* MAIR0 - Index 1. */ portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* Setup privileged flash as Read Only so that privileged tasks can * read it but not modify. */ portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged flash as Read Only by both privileged and * unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup unprivileged syscalls flash as Read Only by both privileged * and unprivileged tasks. All tasks can read it but no-one can modify. */ portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_ONLY ); portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Setup RAM containing kernel data for privileged access only. */ portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); /* Enable mem fault. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; /* Enable MPU with privileged background access i.e. unmapped * regions have privileged access. */ portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) { /* Enable non-secure access to the FPU. */ SecureInit_EnableNSFPUAccess(); } #endif /* configENABLE_TRUSTZONE */ /* CP10 = 11 ==> Full access to FPU i.e. both privileged and * unprivileged code should be able to access FPU. CP11 should be * programmed to the same value as CP10. */ *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) | ( portCPACR_CP11_VALUE << portCPACR_CP11_POS ) ); /* ASPEN = 1 ==> Hardware should automatically preserve floating point * context on exception entry and restore on exception return. * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ void vPortYield( void ) /* PRIVILEGED_FUNCTION */ { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ { portDISABLE_INTERRUPTS(); ulCriticalNesting++; /* Barriers are normally not required but do ensure the code is * completely within the specified behaviour for the architecture. */ __asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "isb" ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ { configASSERT( ulCriticalNesting ); ulCriticalNesting--; if( ulCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { #if ( configENABLE_MPU == 1 ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ #endif /* configENABLE_MPU */ uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) uint32_t ulR0, ulR1; extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ #endif /* configENABLE_TRUSTZONE */ uint8_t ucSVCNumber; /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ ulPC = pulCallerStackAddress[ 6 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { #if ( configENABLE_TRUSTZONE == 1 ) case portSVC_ALLOCATE_SECURE_CONTEXT: /* R0 contains the stack size passed as parameter to the * vPortAllocateSecureContext function. */ ulR0 = pulCallerStackAddress[ 0 ]; #if ( configENABLE_MPU == 1 ) { /* Read the CONTROL register value. */ __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); /* The task that raised the SVC is privileged if Bit[0] * in the CONTROL register is 0. */ ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: /* R0 contains TCB being freed and R1 contains the secure * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) { /* De-prioritize the non-secure exceptions so that the * non-secure pendSV runs at the lowest priority. */ SecureInit_DePrioritizeNSExceptions(); /* Initialize the secure context management system. */ SecureContext_Init(); } #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_FPU == 1 ) { /* Setup the Floating Point Unit (FPU). */ prvSetupFPU(); } #endif /* configENABLE_FPU */ /* Setup the context of the first task so that the first task starts * executing. */ vRestoreContextOfFirstTask(); break; #if ( configENABLE_MPU == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the svc was raised from any of * the system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { vRaisePrivilege(); } break; #endif /* configENABLE_MPU */ default: /* Incorrect SVC call. */ configASSERT( pdFALSE ); } } /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #if ( configENABLE_MPU == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /* *INDENT-ON* */ { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ #if ( configENABLE_MPU == 1 ) { pxTopOfStack--; if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } else { *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ } } #endif /* configENABLE_MPU */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { pxTopOfStack--; *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */ } #endif /* configENABLE_TRUSTZONE */ } #endif /* portPRELOAD_REGISTERS */ return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ prvSetupMPU(); } #endif /* configENABLE_MPU */ /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; /* Start the first task. */ vStartFirstTask(); /* Should never get here as the tasks will now be executing. Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this * functionality by defining configTASK_RETURN_ADDRESS. Call * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __privileged_sram_start__[]; extern uint32_t __privileged_sram_end__[]; #endif /* defined( __ARMCC_VERSION ) */ /* Setup MAIR0. */ xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ if( ulStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged * SRAM is already protected using an MPU region and ARMv8-M does * not allow overlapping MPU regions. */ if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) && ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) ) { xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0; xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0; } else { /* Define the region that allows access to the stack. */ ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ) | ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ); xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_ATTR_INDEX0 ) | ( portMPU_RLAR_REGION_ENABLE ); } } /* User supplied configurable regions. */ for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ ) { /* If xRegions is NULL i.e. the task has not specified any MPU * region, the else part ensures that all the configurable MPU * regions are invalidated. */ if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) ) { /* Translate the generic region definition contained in xRegions * into the ARMv8 specific MPU settings that are then stored in * xMPUSettings. */ ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK; ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1; ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK; /* Start address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) | ( portMPU_REGION_NON_SHAREABLE ); /* RO/RW. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY ); } else { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE ); } /* XN. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 ) { xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER ); } /* End Address. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { /* Attr1 in MAIR0 is configured as device memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1; } else { /* Attr0 in MAIR0 is configured as normal memory. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0; } } else { /* Invalidate the region. */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL; xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL; } lIndex++; } } #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. Interrupt Program * Status Register (IPSR) holds the exception number of the currently-executing * exception or zero for Thread mode.*/ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef __PORT_ASM_H__ #define __PORT_ASM_H__ /* Scheduler includes. */ #include "FreeRTOS.h" /* MPU wrappers includes. */ #include "mpu_wrappers.h" /** * @brief Restore the context of the first task so that the first task starts * executing. */ void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); /** * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * * @note This is a privileged function and should only be called from the kenrel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ) __attribute__( ( naked ) ); /** * @brief Starts the first task. */ void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Disables interrupts. */ uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Enables interrupts. */ void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief PendSV Exception handler. */ void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief SVC Handler. */ void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; /** * @brief Allocate a Secure context for the calling task. * * @param[in] ulSecureStackSize The size of the stack to be allocated on the * secure side for the calling task. */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); /** * @brief Free the task's secure context. * * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. */ void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* __PORT_ASM_H__ */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" EXTERN pxCurrentTCB EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C PUBLIC xIsPrivileged PUBLIC vResetPrivilege PUBLIC vRestoreContextOfFirstTask PUBLIC vRaisePrivilege PUBLIC vStartFirstTask PUBLIC ulSetInterruptMask PUBLIC vClearInterruptMask PUBLIC PendSV_Handler PUBLIC SVC_Handler /*-----------------------------------------------------------*/ /*---------------- Unprivileged Functions -------------------*/ /*-----------------------------------------------------------*/ SECTION .text:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ xIsPrivileged: mrs r0, control /* r0 = CONTROL. */ tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ ite ne movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */ bx lr /* Return. */ /*-----------------------------------------------------------*/ vResetPrivilege: mrs r0, control /* r0 = CONTROL. */ orr r0, r0, #1 /* r0 = r0 | 1. */ msr control, r0 /* CONTROL = r0. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ /*----------------- Privileged Functions --------------------*/ /*-----------------------------------------------------------*/ SECTION privileged_functions:CODE:NOROOT(2) THUMB /*-----------------------------------------------------------*/ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ str r4, [r2] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r3, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ movs r3, #4 /* r3 = 4. */ str r3, [r2] /* Program RNR = 4. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ str r4, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ msr control, r2 /* Set this task's CONTROL value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r3 /* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r2 /* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ vRaisePrivilege: mrs r0, control /* Read the CONTROL register. */ bic r0, r0, #1 /* Clear the bit 0. */ msr control, r0 /* Write back the new CONTROL value. */ bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/ vStartFirstTask: ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ ldr r0, [r0] /* The first entry in vector table is stack pointer. */ msr msp, r0 /* Set the MSP back to the start of the stack. */ cpsie i /* Globally enable interrupts. */ cpsie f dsb isb svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ /*-----------------------------------------------------------*/ ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ /*-----------------------------------------------------------*/ vClearInterruptMask: msr basepri, r0 /* basepri = ulMask. */ dsb isb bx lr /* Return. */ /*-----------------------------------------------------------*/ PendSV_Handler: mrs r0, psp /* Read PSP in r0. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r0!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) mrs r1, psplim /* r1 = PSPLIM. */ mrs r2, control /* r2 = CONTROL. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r1-r11} /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ #else /* configENABLE_MPU */ mrs r2, psplim /* r2 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ #endif /* configENABLE_MPU */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ str r4, [r2] /* Disable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ str r3, [r2] /* Program MAIR0. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ movs r3, #4 /* r3 = 4. */ str r3, [r2] /* Program RNR = 4. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ str r4, [r2] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) ldmia r0!, {r1-r11} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ #else /* configENABLE_MPU */ ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #endif /* configENABLE_MPU */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst r3, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r0!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ #if ( configENABLE_MPU == 1 ) msr psplim, r1 /* Restore the PSPLIM register value for the task. */ msr control, r2 /* Restore the CONTROL register value for the task. */ #else /* configENABLE_MPU */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */ #endif /* configENABLE_MPU */ msr psp, r0 /* Remember the new top of stack for the task. */ bx r3 /*-----------------------------------------------------------*/ SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp b vPortSVCHandler_C /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85_NTZ/non_secure/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif #include "portmacrocommon.h" /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_MVE #error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE. #endif /* configENABLE_MVE */ /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portARCH_NAME "Cortex-M85" #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ #if( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) /*-----------------------------------------------------------*/ /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in * the source code because to do so would cause other compilers to generate * warnings. */ #pragma diag_suppress=Be006 #pragma diag_suppress=Pa082 /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACROCOMMON_H #define PORTMACROCOMMON_H #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------------ * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *------------------------------------------------------------------------------ */ #ifndef configENABLE_FPU #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. #endif /* configENABLE_FPU */ #ifndef configENABLE_MPU #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. #endif /* configENABLE_MPU */ #ifndef configENABLE_TRUSTZONE #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ /** * @brief Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /** * Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) #endif #define portHAS_STACK_OVERFLOW_CHECKING 1 /*-----------------------------------------------------------*/ /** * @brief Extern declarations. */ extern BaseType_t xPortIsInsideInterrupt( void ); extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; #if ( configENABLE_TRUSTZONE == 1 ) extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #endif /* configENABLE_TRUSTZONE */ #if ( configENABLE_MPU == 1 ) extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief MPU specific constants. */ #if ( configENABLE_MPU == 1 ) #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #else #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* MPU regions. */ #define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_RAM_REGION ( 3UL ) #define portSTACK_REGION ( 4UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ /* Device memory attributes used in MPU_MAIR registers. * * 8-bit values encoded as follows: * Bit[7:4] - 0000 - Device Memory * Bit[3:2] - 00 --> Device-nGnRnE * 01 --> Device-nGnRE * 10 --> Device-nGRE * 11 --> Device-GRE * Bit[1:0] - 00, Reserved. */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ /* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ /* Attributes used in MPU_RBAR registers. */ #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ /** * @brief Settings to define an MPU region. */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */ } MPURegionSettings_t; /** * @brief MPU settings as stored in the TCB. */ typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ } xMPU_SETTINGS; /*-----------------------------------------------------------*/ /** * @brief SVC numbers. */ #define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 /*-----------------------------------------------------------*/ /** * @brief Scheduler utilities. */ #define portYIELD() vPortYield() #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /** * @brief Critical section management. */ #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /** * @brief Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /** * @brief Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #if ( configENABLE_TRUSTZONE == 1 ) /** * @brief Allocate a secure context for the task. * * 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 context before it calls any secure function. * * @param[in] ulSecureStackSize The size of the secure stack to be allocated. */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) /** * @brief Called when a task is deleted to delete the task's secure context, * if it has one. * * @param[in] pxTCB The TCB of the task being deleted. */ #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #endif /* configENABLE_TRUSTZONE */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. * * 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, * the privilege is not raised. */ #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 * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() #else #define portIS_PRIVILEGED() #define portRAISE_PRIVILEGE() #define portRESET_PRIVILEGE() #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ /** * @brief Barriers. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif /* PORTMACROCOMMON_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CRx_No_GIC/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #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. #endif #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #ifndef configSETUP_TICK_INTERRUPT #error configSETUP_TICK_INTERRUPT() must be defined in FreeRTOSConfig.h to call the function that sets up the tick interrupt. #endif #ifndef configCLEAR_TICK_INTERRUPT #error configCLEAR_TICK_INTERRUPT must be defined in FreeRTOSConfig.h to clear which ever interrupt was used to generate the tick interrupt. #endif /* A critical section is exited when the critical section nesting count reaches this value. */ #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 ) /* 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 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 context. */ #define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 ) /* Constants required to setup the initial task context. */ #define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, IRQ enabled FIQ enabled. */ #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) #define portTHUMB_MODE_ADDRESS ( 0x01UL ) /* Masks all bits in the APSR other than the mode bits. */ #define portAPSR_MODE_BITS_MASK ( 0x1F ) /* The value of the mode bits in the APSR when the CPU is executing in user mode. */ #define portAPSR_USER_MODE ( 0x10 ) /* 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 debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /*-----------------------------------------------------------*/ /* * Starts the first task executing. This function is necessarily written in * assembly code so is implemented in portASM.s. */ extern void vPortRestoreTaskContext( void ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* 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 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 automatically be set to 0 when the first task is started. */ volatile uint32_t ulCriticalNesting = 9999UL; /* 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. */ volatile uint32_t ulPortTaskHasFPUContext = pdFALSE; /* Set to 1 to pend a context switch from an ISR. */ volatile uint32_t ulPortYieldRequired = pdFALSE; /* Counts the interrupt nesting depth. A context switch is only performed if if the nesting depth is 0. */ volatile uint32_t ulPortInterruptNesting = 0UL; /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { /* Setup the initial stack of the task. The stack is set exactly as expected by the portRESTORE_CONTEXT() macro. 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 GDB does not try decoding a non-existent return address. */ *pxTopOfStack = ( StackType_t ) NULL; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) NULL; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) NULL; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portINITIAL_SPSR; if( ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) != 0x00UL ) { /* The task will start in THUMB mode. */ *pxTopOfStack |= portTHUMB_MODE_BIT; } pxTopOfStack--; /* Next the return address, which in this case is the start of the task. */ *pxTopOfStack = ( StackType_t ) pxCode; pxTopOfStack--; /* Next all the registers other than the stack pointer. */ *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* R14 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; /* The task will start with a critical nesting count of 0 as interrupts are enabled. */ *pxTopOfStack = portNO_CRITICAL_NESTING; pxTopOfStack--; /* The task will start without a floating point context. A task that uses the floating point hardware must call vPortTaskUsesFPU() before executing any floating point instructions. */ *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to its caller as there is nothing to return to. If a task wants to exit it should instead call vTaskDelete( NULL ). Artificially force an assert() to be triggered if configASSERT() is defined, then stop here so application writers can catch the error. */ configASSERT( ulPortInterruptNesting == ~0UL ); portDISABLE_INTERRUPTS(); for( ;; ); } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) { uint32_t ulAPSR; /* Only continue if the CPU is not in User mode. The CPU must be in a Privileged mode for the scheduler to start. */ __asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) ); ulAPSR &= portAPSR_MODE_BITS_MASK; configASSERT( ulAPSR != portAPSR_USER_MODE ); if( ulAPSR != portAPSR_USER_MODE ) { /* Start the timer that generates the tick ISR. */ portDISABLE_INTERRUPTS(); configSETUP_TICK_INTERRUPT(); /* Start the first task executing. */ vPortRestoreTaskContext(); } /* 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 possible value. prvTaskExitError() is referenced to prevent a compiler warning about it being defined but not referenced in the case that the user defines their own exit address. */ ( void ) prvTaskExitError; return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); /* Now interrupts are disabled ulCriticalNesting can be accessed directly. Increment ulCriticalNesting to keep a count of how many times portENTER_CRITICAL() has been called. */ ulCriticalNesting++; /* 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 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 assert function also uses a critical section. */ if( ulCriticalNesting == 1 ) { configASSERT( ulPortInterruptNesting == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { if( ulCriticalNesting > portNO_CRITICAL_NESTING ) { /* Decrement the nesting count as the critical section is being exited. */ ulCriticalNesting--; /* If the nesting level has reached zero then all interrupt priorities must be re-enabled. */ if( ulCriticalNesting == portNO_CRITICAL_NESTING ) { /* Critical nesting has reached zero so all interrupt priorities should be unmasked. */ portENABLE_INTERRUPTS(); } } } /*-----------------------------------------------------------*/ void FreeRTOS_Tick_Handler( void ) { uint32_t ulInterruptStatus; ulInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { ulPortYieldRequired = pdTRUE; } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulInterruptStatus ); configCLEAR_TICK_INTERRUPT(); } /*-----------------------------------------------------------*/ void vPortTaskUsesFPU( void ) { uint32_t ulInitialFPSCR = 0; /* 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). */ ulPortTaskHasFPUContext = pdTRUE; /* Initialise the floating point status register. */ __asm volatile ( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) ); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CRx_No_GIC/portASM.s ================================================ ;/* ; * FreeRTOS Kernel V10.5.1 ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * this software and associated documentation files (the "Software"), to deal in ; * the Software without restriction, including without limitation the rights to ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * the Software, and to permit persons to whom the Software is furnished to do so, ; * subject to the following conditions: ; * ; * The above copyright notice and this permission notice shall be included in all ; * copies or substantial portions of the Software. ; * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * ; * https://www.FreeRTOS.org ; * https://github.com/FreeRTOS ; * ; */ #include "FreeRTOSConfig.h" SECTION .text:CODE:ROOT(2) arm /* Variables and functions. */ EXTERN pxCurrentTCB EXTERN vTaskSwitchContext EXTERN vApplicationIRQHandler EXTERN ulPortInterruptNesting EXTERN ulPortTaskHasFPUContext EXTERN ulPortYieldRequired EXTERN ulCriticalNesting PUBLIC FreeRTOS_IRQ_Handler PUBLIC FreeRTOS_SVC_Handler PUBLIC vPortRestoreTaskContext SYS_MODE EQU 0x1f SVC_MODE EQU 0x13 IRQ_MODE EQU 0x12 portSAVE_CONTEXT MACRO /* Save the LR and SPSR onto the system mode stack before switching to system mode to save the remaining system mode registers. */ SRSDB sp!, #SYS_MODE CPS #SYS_MODE PUSH {R0-R12, R14} /* Push the critical nesting count. */ LDR R2, =ulCriticalNesting LDR R1, [R2] PUSH {R1} /* Does the task have a floating point context that needs saving? If ulPortTaskHasFPUContext is 0 then no. */ LDR R2, =ulPortTaskHasFPUContext LDR R3, [R2] CMP R3, #0 /* Save the floating point context, if any. */ FMRXNE R1, FPSCR VPUSHNE {D0-D15} #if configFPU_D32 == 1 VPUSHNE {D16-D31} #endif /* configFPU_D32 */ PUSHNE {R1} /* Save ulPortTaskHasFPUContext itself. */ PUSH {R3} /* Save the stack pointer in the TCB. */ LDR R0, =pxCurrentTCB LDR R1, [R0] STR SP, [R1] ENDM ; /**********************************************************************/ portRESTORE_CONTEXT MACRO /* Set the SP to point to the stack of the task being restored. */ LDR R0, =pxCurrentTCB LDR R1, [R0] LDR SP, [R1] /* Is there a floating point context to restore? If the restored ulPortTaskHasFPUContext is zero then no. */ LDR R0, =ulPortTaskHasFPUContext POP {R1} STR R1, [R0] CMP R1, #0 /* Restore the floating point context, if any. */ POPNE {R0} #if configFPU_D32 == 1 VPOPNE {D16-D31} #endif /* configFPU_D32 */ VPOPNE {D0-D15} VMSRNE FPSCR, R0 /* Restore the critical section nesting depth. */ LDR R0, =ulCriticalNesting POP {R1} STR R1, [R0] /* Restore all system mode registers other than the SP (which is already being used). */ POP {R0-R12, R14} /* Return to the task code, loading CPSR on the way. */ RFEIA sp! ENDM /****************************************************************************** * SVC handler is used to yield. *****************************************************************************/ FreeRTOS_SVC_Handler: /* Save the context of the current task and select a new task to run. */ portSAVE_CONTEXT LDR R0, =vTaskSwitchContext BLX R0 portRESTORE_CONTEXT /****************************************************************************** * vPortRestoreTaskContext is used to start the scheduler. *****************************************************************************/ vPortRestoreTaskContext: /* Switch to system mode. */ CPS #SYS_MODE portRESTORE_CONTEXT FreeRTOS_IRQ_Handler: /* Return to the interrupted instruction. */ SUB lr, lr, #4 /* Push the return address and SPSR. */ PUSH {lr} MRS lr, SPSR PUSH {lr} /* Change to supervisor mode to allow reentry. */ CPS #SVC_MODE /* Push used registers. */ PUSH {r0-r3, r12} /* Increment nesting count. r3 holds the address of ulPortInterruptNesting for future use. r1 holds the original ulPortInterruptNesting value for future use. */ LDR r3, =ulPortInterruptNesting LDR r1, [r3] ADD r0, r1, #1 STR r0, [r3] /* Ensure bit 2 of the stack pointer is clear. r2 holds the bit 2 value for future use. */ MOV r0, sp AND r2, r0, #4 SUB sp, sp, r2 /* Call the interrupt handler. */ PUSH {r0-r3, lr} LDR r1, =vApplicationIRQHandler BLX r1 POP {r0-r3, lr} ADD sp, sp, r2 CPSID i DSB ISB /* Write to the EOI register. */ LDR r2, =configEOI_ADDRESS STR r0, [r2] /* Restore the old nesting count. */ STR r1, [r3] /* A context switch is never performed if the nesting count is not 0. */ CMP r1, #0 BNE exit_without_switch /* Did the interrupt request a context switch? r1 holds the address of ulPortYieldRequired and r0 the value of ulPortYieldRequired for future use. */ LDR r1, =ulPortYieldRequired LDR r0, [r1] CMP r0, #0 BNE switch_before_exit exit_without_switch: /* No context switch. Restore used registers, LR_irq and SPSR before returning. */ POP {r0-r3, r12} CPS #IRQ_MODE POP {LR} MSR SPSR_cxsf, LR POP {LR} MOVS PC, LR switch_before_exit: /* A context swtich is to be performed. Clear the context switch pending flag. */ MOV r0, #0 STR r0, [r1] /* Restore used registers, LR-irq and SPSR before saving the context to the task stack. */ POP {r0-r3, r12} CPS #IRQ_MODE POP {LR} MSR SPSR_cxsf, LR POP {LR} portSAVE_CONTEXT /* Call the function that selects the new task to execute. vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD instructions, or 8 byte aligned stack allocated data. LR does not need saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. */ LDR R0, =vTaskSwitchContext BLX R0 /* Restore the context of, and branch to, the task selected to execute next. */ portRESTORE_CONTEXT END ================================================ FILE: FreeRTOS-comparison/portable/IAR/ARM_CRx_No_GIC/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #include #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 /*-----------------------------------------------------------*/ /* Hardware specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Task utilities. */ /* Called at the end of an ISR that can cause a context switch. */ #define portEND_SWITCHING_ISR( xSwitchRequired )\ { \ extern volatile uint32_t ulPortYieldRequired; \ \ if( xSwitchRequired != pdFALSE ) \ { \ ulPortYieldRequired = pdTRUE; \ } \ } #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD() __asm volatile ( "SWI 0 \n" \ "ISB " ); /*----------------------------------------------------------- * Critical section control *----------------------------------------------------------*/ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); extern uint32_t ulPortSetInterruptMask( void ); extern void vPortClearInterruptMask( uint32_t ulNewMaskValue ); extern void vPortInstallFreeRTOSVectorTable( void ); /* The I bit within the CPSR. */ #define portINTERRUPT_ENABLE_BIT ( 1 << 7 ) /* In the absence of a priority mask register, these functions and macros globally enable and disable interrupts. */ #define portENTER_CRITICAL() vPortEnterCritical(); #define portEXIT_CRITICAL() vPortExitCritical(); #define portENABLE_INTERRUPTS() __asm volatile ( "CPSIE i \n" ); #define portDISABLE_INTERRUPTS() __asm volatile ( "CPSID i \n" \ "DSB \n" \ "ISB " ); #pragma inline static inline uint32_t portINLINE_SET_INTERRUPT_MASK_FROM_ISR( void ) { volatile uint32_t ulCPSR; __asm volatile ( "MRS %0, CPSR" : "=r" (ulCPSR) ); ulCPSR &= portINTERRUPT_ENABLE_BIT; portDISABLE_INTERRUPTS(); return ulCPSR; } #define portSET_INTERRUPT_MASK_FROM_ISR() portINLINE_SET_INTERRUPT_MASK_FROM_ISR() #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) do { if( x == 0 ) portENABLE_INTERRUPTS(); } while( 0 ) /*-----------------------------------------------------------*/ /* 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 macros is used. */ #define portTASK_FUNCTION_PROTO( 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 handler for whichever peripheral is used to generate the RTOS tick. */ void FreeRTOS_Tick_Handler( void ); /* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() before any floating point instructions are executed. */ void vPortTaskUsesFPU( void ); #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() #define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) #define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL ) /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) __CLZ( uxReadyPriorities ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #define portNOP() __asm volatile( "NOP" ) #define portINLINE inline /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in the source code because to do so would cause other compilers to generate warnings. */ #pragma diag_suppress=Pe191 #pragma diag_suppress=Pa082 #ifdef __cplusplus } /* extern C */ #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/LPC2000/ISR_Support.h ================================================ ;/* ; * FreeRTOS Kernel V10.5.1 ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * this software and associated documentation files (the "Software"), to deal in ; * the Software without restriction, including without limitation the rights to ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * the Software, and to permit persons to whom the Software is furnished to do so, ; * subject to the following conditions: ; * ; * The above copyright notice and this permission notice shall be included in all ; * copies or substantial portions of the Software. ; * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * ; * https://www.FreeRTOS.org ; * https://github.com/FreeRTOS ; * ; */ EXTERN pxCurrentTCB EXTERN ulCriticalNesting ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Context save and restore macro definitions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; portSAVE_CONTEXT MACRO ; Push R0 as we are going to use the register. STMDB SP!, {R0} ; Set R0 to point to the task stack pointer. STMDB SP, {SP}^ NOP SUB SP, SP, #4 LDMIA SP!, {R0} ; Push the return address onto the stack. STMDB R0!, {LR} ; Now we have saved LR we can use it instead of R0. MOV LR, R0 ; Pop R0 so we can save it onto the system mode stack. LDMIA SP!, {R0} ; Push all the system mode registers onto the task stack. STMDB LR, {R0-LR}^ NOP SUB LR, LR, #60 ; Push the SPSR onto the task stack. MRS R0, SPSR STMDB LR!, {R0} LDR R0, =ulCriticalNesting LDR R0, [R0] STMDB LR!, {R0} ; Store the new top of stack for the task. LDR R1, =pxCurrentTCB LDR R0, [R1] STR LR, [R0] ENDM portRESTORE_CONTEXT MACRO ; Set the LR to the task stack. LDR R1, =pxCurrentTCB LDR R0, [R1] LDR LR, [R0] ; The critical nesting depth is the first item on the stack. ; Load it into the ulCriticalNesting variable. LDR R0, =ulCriticalNesting LDMFD LR!, {R1} STR R1, [R0] ; Get the SPSR from the stack. LDMFD LR!, {R0} MSR SPSR_cxsf, R0 ; Restore all system mode registers for the task. LDMFD LR, {R0-R14}^ NOP ; Restore the return address. LDR LR, [LR, #+60] ; And return - correcting the offset in the LR to obtain the ; correct address. SUBS PC, LR, #4 ENDM ================================================ FILE: FreeRTOS-comparison/portable/IAR/LPC2000/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the Philips ARM7 port. *----------------------------------------------------------*/ /* Changes from V3.2.2 + Bug fix - The prescale value for the timer setup is now written to T0PR instead of T0PC. This bug would have had no effect unless a prescale value was actually used. */ /* Standard includes. */ #include #include /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* Constants required to setup the tick ISR. */ #define portENABLE_TIMER ( ( uint8_t ) 0x01 ) #define portPRESCALE_VALUE 0x00 #define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 ) #define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 ) /* Constants required to setup the initial stack. */ #define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */ #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) #define portINSTRUCTION_SIZE ( ( StackType_t ) 4 ) /* Constants required to setup the PIT. */ #define portPIT_CLOCK_DIVISOR ( ( uint32_t ) 16 ) #define portPIT_COUNTER_VALUE ( ( ( configCPU_CLOCK_HZ / portPIT_CLOCK_DIVISOR ) / 1000UL ) * portTICK_PERIOD_MS ) /* Constants required to handle interrupts. */ #define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 ) #define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 ) /* Constants required to handle critical sections. */ #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 ) #define portINT_LEVEL_SENSITIVE 0 #define portPIT_ENABLE ( ( uint16_t ) 0x1 << 24 ) #define portPIT_INT_ENABLE ( ( uint16_t ) 0x1 << 25 ) /* Constants required to setup the VIC for the tick ISR. */ #define portTIMER_VIC_CHANNEL ( ( uint32_t ) 0x0004 ) #define portTIMER_VIC_CHANNEL_BIT ( ( uint32_t ) 0x0010 ) #define portTIMER_VIC_ENABLE ( ( uint32_t ) 0x0020 ) /*-----------------------------------------------------------*/ /* Setup the PIT to generate the tick interrupts. */ static void prvSetupTimerInterrupt( void ); /* ulCriticalNesting will get set to zero when the first task starts. It cannot be initialised to 0 as this will cause interrupts to be enabled during the kernel initialisation process. */ uint32_t ulCriticalNesting = ( uint32_t ) 9999; /*-----------------------------------------------------------*/ /* * Initialise the stack of a task to look exactly as if a call to * portSAVE_CONTEXT had been called. * * See header file for description. */ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { StackType_t *pxOriginalTOS; pxOriginalTOS = pxTopOfStack; /* Setup the initial stack of the task. The stack is set exactly as expected by the portRESTORE_CONTEXT() macro. */ /* 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 as it would within an IRQ ISR. */ *pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xaaaaaaaa; /* R14 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */ pxTopOfStack--; /* When the task starts is will expect to find the function parameter in R0. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; /* The status register is set for system mode, with interrupts enabled. */ *pxTopOfStack = ( StackType_t ) portINITIAL_SPSR; if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00UL ) { /* We want the task to start in thumb mode. */ *pxTopOfStack |= portTHUMB_MODE_BIT; } pxTopOfStack--; /* 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 tasks context. */ *pxTopOfStack = portNO_CRITICAL_NESTING; return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) { extern void vPortStartFirstTask( void ); /* Start the timer that generates the tick ISR. Interrupts are disabled here already. */ prvSetupTimerInterrupt(); /* Start the first task. */ vPortStartFirstTask(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* It is unlikely that the ARM port will require this function as there is nothing to return to. */ } /*-----------------------------------------------------------*/ #if configUSE_PREEMPTION == 0 /* The cooperative scheduler requires a normal IRQ service routine to simply increment the system tick. */ static __arm __irq void vPortNonPreemptiveTick( void ); static __arm __irq void vPortNonPreemptiveTick( void ) { /* Increment the tick count - which may wake some tasks but as the preemptive scheduler is not being used any woken task is not given processor time no matter what its priority. */ xTaskIncrementTick(); /* Ready for the next interrupt. */ T0IR = portTIMER_MATCH_ISR_BIT; VICVectAddr = portCLEAR_VIC_INTERRUPT; } #else /* This function is called from an asm wrapper, so does not require the __irq keyword. */ void vPortPreemptiveTick( void ); void vPortPreemptiveTick( void ) { /* Increment the tick counter. */ if( xTaskIncrementTick() != pdFALSE ) { /* The new tick value might unblock a task. Ensure the highest task that is ready to execute is the task that will execute when the tick ISR exits. */ vTaskSwitchContext(); } /* Ready for the next interrupt. */ T0IR = portTIMER_MATCH_ISR_BIT; VICVectAddr = portCLEAR_VIC_INTERRUPT; } #endif /*-----------------------------------------------------------*/ static void prvSetupTimerInterrupt( void ) { uint32_t ulCompareMatch; /* A 1ms tick does not require the use of the timer prescale. This is defaulted to zero but can be used if necessary. */ T0PR = portPRESCALE_VALUE; /* Calculate the match value required for our wanted tick rate. */ ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ; /* Protect against divide by zero. Using an if() statement still results in a warning - hence the #if. */ #if portPRESCALE_VALUE != 0 { ulCompareMatch /= ( portPRESCALE_VALUE + 1 ); } #endif T0MR0 = ulCompareMatch; /* Generate tick with timer 0 compare match. */ T0MCR = portRESET_COUNT_ON_MATCH | portINTERRUPT_ON_MATCH; /* Setup the VIC for the timer. */ VICIntSelect &= ~( portTIMER_VIC_CHANNEL_BIT ); VICIntEnable |= portTIMER_VIC_CHANNEL_BIT; /* The ISR installed depends on whether the preemptive or cooperative scheduler is being used. */ #if configUSE_PREEMPTION == 1 { extern void ( vPortPreemptiveTickEntry )( void ); VICVectAddr0 = ( uint32_t ) vPortPreemptiveTickEntry; } #else { extern void ( vNonPreemptiveTick )( void ); VICVectAddr0 = ( int32_t ) vPortNonPreemptiveTick; } #endif VICVectCntl0 = portTIMER_VIC_CHANNEL | portTIMER_VIC_ENABLE; /* Start the timer - interrupts are disabled when this function is called so it is okay to do this here. */ T0TCR = portENABLE_TIMER; } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { /* Disable interrupts first! */ __disable_interrupt(); /* Now interrupts are disabled ulCriticalNesting can be accessed directly. Increment ulCriticalNesting to keep a count of how many times portENTER_CRITICAL() has been called. */ ulCriticalNesting++; } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { if( ulCriticalNesting > portNO_CRITICAL_NESTING ) { /* Decrement the nesting count as we are leaving a critical section. */ ulCriticalNesting--; /* If the nesting level has reached zero then interrupts should be re-enabled. */ if( ulCriticalNesting == portNO_CRITICAL_NESTING ) { __enable_interrupt(); } } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/LPC2000/portasm.s79 ================================================ ;/* ; * FreeRTOS Kernel V10.5.1 ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * this software and associated documentation files (the "Software"), to deal in ; * the Software without restriction, including without limitation the rights to ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * the Software, and to permit persons to whom the Software is furnished to do so, ; * subject to the following conditions: ; * ; * The above copyright notice and this permission notice shall be included in all ; * copies or substantial portions of the Software. ; * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * ; * https://www.FreeRTOS.org ; * https://github.com/FreeRTOS ; * ; */ RSEG ICODE:CODE CODE32 EXTERN vTaskSwitchContext EXTERN vPortPreemptiveTick PUBLIC vPortPreemptiveTickEntry PUBLIC vPortYieldProcessor PUBLIC vPortStartFirstTask #include "FreeRTOSConfig.h" #include "ISR_Support.h" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Starting the first task is just a matter of restoring the context that ; was created by pxPortInitialiseStack(). ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; vPortStartFirstTask: portRESTORE_CONTEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Manual context switch function. This is the SWI hander. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; vPortYieldProcessor: ADD LR, LR, #4 ; Add 4 to the LR to make the LR appear exactly ; as if the context was saved during and IRQ ; handler. portSAVE_CONTEXT ; Save the context of the current task... LDR R0, =vTaskSwitchContext ; before selecting the next task to execute. mov lr, pc BX R0 portRESTORE_CONTEXT ; Restore the context of the selected task. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Preemptive context switch function. This will only ever get installed if ; portUSE_PREEMPTION is set to 1 in portmacro.h. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; vPortPreemptiveTickEntry: #if configUSE_PREEMPTION == 1 portSAVE_CONTEXT ; Save the context of the current task... LDR R0, =vPortPreemptiveTick; before selecting the next task to execute. mov lr, pc BX R0 portRESTORE_CONTEXT ; Restore the context of the selected task. #endif END ================================================ FILE: FreeRTOS-comparison/portable/IAR/LPC2000/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #include #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #endif /*-----------------------------------------------------------*/ /* Hardware specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portYIELD() asm ( "SWI 0" ) #define portNOP() asm ( "NOP" ) /*-----------------------------------------------------------*/ /* Critical section handling. */ __arm __interwork void vPortDisableInterruptsFromThumb( void ); __arm __interwork void vPortEnableInterruptsFromThumb( void ); __arm __interwork void vPortEnterCritical( void ); __arm __interwork void vPortExitCritical( void ); #define portDISABLE_INTERRUPTS() __disable_interrupt() #define portENABLE_INTERRUPTS() __enable_interrupt() #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /* Task utilities. */ #define portEND_SWITCHING_ISR( xSwitchRequired ) \ { \ extern void vTaskSwitchContext( void ); \ \ if( xSwitchRequired ) \ { \ vTaskSwitchContext(); \ } \ } /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/MSP430/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the MSP430 port. *----------------------------------------------------------*/ /* Constants required for hardware setup. The tick ISR runs off the ACLK, not the MCLK. */ #define portACLK_FREQUENCY_HZ ( ( TickType_t ) 32768 ) #define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 ) #define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x08 ) /* We require the address of the pxCurrentTCB variable, but don't want to know any details of its type. */ typedef void TCB_t; extern volatile TCB_t * volatile pxCurrentTCB; /* 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 critical section is exited the count is decremented - with interrupts only being re-enabled if the count is zero. 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 sequence. */ volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING; /*-----------------------------------------------------------*/ /* * Sets up the periodic ISR used for the RTOS tick. This uses timer 0, but * could have alternatively used the watchdog timer or timer 1. */ void vPortSetupTimerInterrupt( void ); /*-----------------------------------------------------------*/ /* * Initialise the stack of a task to look exactly as if a call to * portSAVE_CONTEXT had been called. * * See the header file portable.h. */ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { /* 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. *pxTopOfStack = ( StackType_t ) 0x1111; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x2222; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x3333; pxTopOfStack--; */ /* The msp430 automatically pushes the PC then SR onto the stack before executing an ISR. We want the stack to look just as if this has happened so place a pointer to the start of the task on the stack first - followed by the flags we want the task to use when it starts up. */ *pxTopOfStack = ( StackType_t ) pxCode; pxTopOfStack--; *pxTopOfStack = portFLAGS_INT_ENABLED; pxTopOfStack--; /* Next the general purpose registers. */ *pxTopOfStack = ( StackType_t ) 0x4444; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x5555; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x6666; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x7777; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x8888; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x9999; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xaaaa; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xbbbb; pxTopOfStack--; /* When the task starts is will expect to find the function parameter in R15. */ *pxTopOfStack = ( StackType_t ) pvParameters; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xdddd; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xeeee; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xffff; pxTopOfStack--; /* 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 initially set to zero. */ *pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING; /* 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. */ return pxTopOfStack; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* It is unlikely that the MSP430 port will get stopped. If required simply disable the tick interrupt here. */ } /*-----------------------------------------------------------*/ /* * Hardware initialisation to generate the RTOS tick. This uses timer 0 * but could alternatively use the watchdog timer or timer 1. */ void vPortSetupTimerInterrupt( void ) { /* Ensure the timer is stopped. */ TACTL = 0; /* Run the timer of the ACLK. */ TACTL = TASSEL_1; /* Clear everything to start with. */ TACTL |= TACLR; /* Set the compare match value according to the tick rate we want. */ TACCR0 = portACLK_FREQUENCY_HZ / configTICK_RATE_HZ; /* Enable the interrupts. */ TACCTL0 = CCIE; /* Start up clean. */ TACTL |= TACLR; /* Up mode. */ TACTL |= MC_1; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/IAR/MSP430/portasm.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTASM_H #define PORTASM_H portSAVE_CONTEXT macro IMPORT pxCurrentTCB IMPORT usCriticalNesting /* Save the remaining registers. */ push r4 push r5 push r6 push r7 push r8 push r9 push r10 push r11 push r12 push r13 push r14 push r15 mov.w &usCriticalNesting, r14 push r14 mov.w &pxCurrentTCB, r12 mov.w r1, 0(r12) endm /*-----------------------------------------------------------*/ portRESTORE_CONTEXT macro mov.w &pxCurrentTCB, r12 mov.w @r12, r1 pop r15 mov.w r15, &usCriticalNesting pop r15 pop r14 pop r13 pop r12 pop r11 pop r10 pop r9 pop r8 pop r7 pop r6 pop r5 pop r4 /* The last thing on the stack will be the status register. Ensure the power down bits are clear ready for the next time this power down register is popped from the stack. */ bic.w #0xf0,0(SP) reti endm /*-----------------------------------------------------------*/ #endif ================================================ FILE: FreeRTOS-comparison/portable/IAR/MSP430/portext.s43 ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #include "FreeRTOSConfig.h" #include "portasm.h" IMPORT xTaskIncrementTick IMPORT vTaskSwitchContext IMPORT vPortSetupTimerInterrupt EXPORT vTickISR EXPORT vPortYield EXPORT xPortStartScheduler RSEG CODE /* * The RTOS tick ISR. * * If the cooperative scheduler is in use this simply increments the tick * count. * * If the preemptive scheduler is in use a context switch can also occur. */ vTickISR: portSAVE_CONTEXT call #xTaskIncrementTick cmp.w #0x0, R12 jeq SkipContextSwitch call #vTaskSwitchContext SkipContextSwitch: portRESTORE_CONTEXT /*-----------------------------------------------------------*/ /* * Manual context switch called by the portYIELD() macro. */ vPortYield: /* Mimic an interrupt by pushing the SR. */ push SR /* Now the SR is stacked we can disable interrupts. */ dint /* Save the context of the current task. */ portSAVE_CONTEXT /* Switch to the highest priority task that is ready to run. */ call #vTaskSwitchContext /* Restore the context of the new task. */ portRESTORE_CONTEXT /*-----------------------------------------------------------*/ /* * Start off the scheduler by initialising the RTOS tick timer, then restoring * the context of the first task. */ xPortStartScheduler: /* Setup the hardware to generate the tick. Interrupts are disabled when this function is called. */ call #vPortSetupTimerInterrupt /* Restore the context of the first task that is going to run. */ portRESTORE_CONTEXT /*-----------------------------------------------------------*/ /* Install vTickISR as the timer A0 interrupt. */ ASEG ORG 0xFFE0 + TIMERA0_VECTOR _vTickISR_: DC16 vTickISR END ================================================ FILE: FreeRTOS-comparison/portable/IAR/MSP430/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT int #define portSTACK_TYPE uint16_t #define portBASE_TYPE short typedef portSTACK_TYPE StackType_t; typedef short BaseType_t; typedef unsigned short UBaseType_t; #if( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #endif /*-----------------------------------------------------------*/ /* Interrupt control macros. */ #define portDISABLE_INTERRUPTS() _DINT(); _NOP() #define portENABLE_INTERRUPTS() _EINT(); _NOP() /*-----------------------------------------------------------*/ /* Critical section control macros. */ #define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 ) #define portENTER_CRITICAL() \ { \ extern volatile uint16_t usCriticalNesting; \ \ portDISABLE_INTERRUPTS(); \ \ /* Now interrupts are disabled usCriticalNesting can be accessed */ \ /* directly. Increment ulCriticalNesting to keep a count of how many */ \ /* times portENTER_CRITICAL() has been called. */ \ usCriticalNesting++; \ } #define portEXIT_CRITICAL() \ { \ extern volatile uint16_t usCriticalNesting; \ \ if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \ { \ /* Decrement the nesting count as we are leaving a critical section. */ \ usCriticalNesting--; \ \ /* If the nesting level has reached zero then interrupts should be */ \ /* re-enabled. */ \ if( usCriticalNesting == portNO_CRITICAL_SECTION_NESTING ) \ { \ portENABLE_INTERRUPTS(); \ } \ } \ } /*-----------------------------------------------------------*/ /* Task utilities. */ /* * Manual context switch called by portYIELD or taskYIELD. */ extern void vPortYield( void ); #define portYIELD() vPortYield() /*-----------------------------------------------------------*/ /* Hardware specifics. */ #define portBYTE_ALIGNMENT 2 #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portNOP() #define portPOINTER_SIZE_TYPE uint16_t /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) #if configINTERRUPT_EXAMPLE_METHOD == 2 extern void vTaskSwitchContext( void ); #define portYIELD_FROM_ISR( x ) do { if( x ) vTaskSwitchContext(); } while( 0 ) #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/MSP430X/data_model.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef DATA_MODEL_H #define DATA_MODEL_H #if __DATA_MODEL__ == __DATA_MODEL_SMALL__ #define pushm_x pushm.w #define popm_x popm.w #define push_x push.w #define pop_x pop.w #define mov_x mov.w #define cmp_x cmp.w #endif #if __DATA_MODEL__ == __DATA_MODEL_MEDIUM__ #define pushm_x pushm.a #define popm_x popm.a #define push_x pushx.a #define pop_x popx.a #define mov_x mov.w #define cmp_x cmp.w #endif #if __DATA_MODEL__ == __DATA_MODEL_LARGE__ #define pushm_x pushm.a #define popm_x popm.a #define push_x pushx.a #define pop_x popx.a #define mov_x movx.a #define cmp_x cmpx.a #endif #ifndef pushm_x #error The assembler options must define one of the following symbols: __DATA_MODEL_SMALL__, __DATA_MODEL_MEDIUM__, or __DATA_MODEL_LARGE__ #endif #endif /* DATA_MODEL_H */ ================================================ FILE: FreeRTOS-comparison/portable/IAR/MSP430X/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the MSP430X port. *----------------------------------------------------------*/ /* Constants required for hardware setup. The tick ISR runs off the ACLK, not the MCLK. */ #define portACLK_FREQUENCY_HZ ( ( TickType_t ) 32768 ) #define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 ) #define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x08 ) /* We require the address of the pxCurrentTCB variable, but don't want to know any details of its type. */ typedef void TCB_t; extern volatile TCB_t * volatile pxCurrentTCB; /* 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 critical section is exited the count is decremented - with interrupts only being re-enabled if the count is zero. 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 sequence. */ volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING; /*-----------------------------------------------------------*/ /* * Sets up the periodic ISR used for the RTOS tick. This uses timer 0, but * could have alternatively used the watchdog timer or timer 1. */ void vPortSetupTimerInterrupt( void ); /*-----------------------------------------------------------*/ /* * Initialise the stack of a task to look exactly as if a call to * portSAVE_CONTEXT had been called. * * See the header file portable.h. */ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { uint16_t *pusTopOfStack; uint32_t *pulTopOfStack; /* 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. *pxTopOfStack = ( StackType_t ) 0x1111; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x2222; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x3333; */ /* StackType_t is either 16 bits or 32 bits depending on the data model. Some stacked items do not change size depending on the data model so have to be explicitly cast to the correct size so this function will work whichever data model is being used. */ if( sizeof( StackType_t ) == sizeof( uint16_t ) ) { /* Make room for a 20 bit value stored as a 32 bit value. */ pusTopOfStack = ( uint16_t * ) pxTopOfStack; pusTopOfStack--; pulTopOfStack = ( uint32_t * ) pusTopOfStack; } else { pulTopOfStack = ( uint32_t * ) pxTopOfStack; } *pulTopOfStack = ( uint32_t ) pxCode; pusTopOfStack = ( uint16_t * ) pulTopOfStack; pusTopOfStack--; *pusTopOfStack = portFLAGS_INT_ENABLED; pusTopOfStack -= ( sizeof( StackType_t ) / 2 ); /* From here on the size of stacked items depends on the memory model. */ pxTopOfStack = ( StackType_t * ) pusTopOfStack; /* Next the general purpose registers. */ #ifdef PRELOAD_REGISTER_VALUES *pxTopOfStack = ( StackType_t ) 0xffff; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xeeee; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xdddd; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xbbbb; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xaaaa; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x9999; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x8888; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x5555; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x6666; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x5555; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x4444; pxTopOfStack--; #else pxTopOfStack -= 3; *pxTopOfStack = ( StackType_t ) pvParameters; pxTopOfStack -= 9; #endif /* 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 initially set to zero. */ *pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING; /* 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. */ return pxTopOfStack; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* It is unlikely that the MSP430 port will get stopped. If required simply disable the tick interrupt here. */ } /*-----------------------------------------------------------*/ /* * Hardware initialisation to generate the RTOS tick. */ void vPortSetupTimerInterrupt( void ) { vApplicationSetupTimerInterrupt(); } /*-----------------------------------------------------------*/ #pragma vector=configTICK_VECTOR __interrupt __raw void vTickISREntry( void ) { extern void vPortTickISR( void ); __bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF ); vPortTickISR(); } ================================================ FILE: FreeRTOS-comparison/portable/IAR/MSP430X/portext.s43 ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #include "msp430.h" #include "FreeRTOSConfig.h" #include "data_model.h" IMPORT xTaskIncrementTick IMPORT vTaskSwitchContext IMPORT vPortSetupTimerInterrupt IMPORT pxCurrentTCB IMPORT usCriticalNesting EXPORT vPortTickISR EXPORT vPortYield EXPORT xPortStartScheduler portSAVE_CONTEXT macro /* Save the remaining registers. */ pushm_x #12, r15 mov.w &usCriticalNesting, r14 push_x r14 mov_x &pxCurrentTCB, r12 mov_x sp, 0( r12 ) endm /*-----------------------------------------------------------*/ portRESTORE_CONTEXT macro mov_x &pxCurrentTCB, r12 mov_x @r12, sp pop_x r15 mov.w r15, &usCriticalNesting popm_x #12, r15 nop pop.w sr nop reta endm /*-----------------------------------------------------------*/ /* * The RTOS tick ISR. * * If the cooperative scheduler is in use this simply increments the tick * count. * * If the preemptive scheduler is in use a context switch can also occur. */ RSEG CODE EVEN vPortTickISR: /* The sr is not saved in portSAVE_CONTEXT() because vPortYield() needs to save it manually before it gets modified (interrupts get disabled). Entering through this interrupt means the SR is already on the stack, but this keeps the stack frames identical. */ push.w sr portSAVE_CONTEXT calla #xTaskIncrementTick cmp.w #0x0, R12 jeq SkipContextSwitch calla #vTaskSwitchContext SkipContextSwitch: portRESTORE_CONTEXT /*-----------------------------------------------------------*/ /* * Manual context switch called by the portYIELD() macro. */ EVEN vPortYield: /* The sr needs saving before it is modified. */ push.w sr /* Now the SR is stacked interrupts can be disabled. */ dint nop /* Save the context of the current task. */ portSAVE_CONTEXT /* Select the next task to run. */ calla #vTaskSwitchContext /* Restore the context of the new task. */ portRESTORE_CONTEXT /*-----------------------------------------------------------*/ /* * Start off the scheduler by initialising the RTOS tick timer, then restoring * the context of the first task. */ EVEN xPortStartScheduler: /* Setup the hardware to generate the tick. Interrupts are disabled when this function is called. */ calla #vPortSetupTimerInterrupt /* Restore the context of the first task that is going to run. */ portRESTORE_CONTEXT /*-----------------------------------------------------------*/ END ================================================ FILE: FreeRTOS-comparison/portable/IAR/MSP430X/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Hardware includes. */ #include "msp430.h" /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT int #define portBASE_TYPE short /* The stack type changes depending on the data model. */ #if( __DATA_MODEL__ == __DATA_MODEL_SMALL__ ) #define portSTACK_TYPE uint16_t #define portPOINTER_SIZE_TYPE uint16_t #else #define portSTACK_TYPE uint32_t #endif typedef portSTACK_TYPE StackType_t; typedef short BaseType_t; typedef unsigned short UBaseType_t; #if( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #endif /*-----------------------------------------------------------*/ /* Interrupt control macros. */ #define portDISABLE_INTERRUPTS() _DINT(); _NOP() #define portENABLE_INTERRUPTS() _EINT(); _NOP() /*-----------------------------------------------------------*/ /* Critical section control macros. */ #define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 ) #define portENTER_CRITICAL() \ { \ extern volatile uint16_t usCriticalNesting; \ \ portDISABLE_INTERRUPTS(); \ \ /* Now interrupts are disabled usCriticalNesting can be accessed */ \ /* directly. Increment ulCriticalNesting to keep a count of how many */ \ /* times portENTER_CRITICAL() has been called. */ \ usCriticalNesting++; \ } #define portEXIT_CRITICAL() \ { \ extern volatile uint16_t usCriticalNesting; \ \ if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \ { \ /* Decrement the nesting count as we are leaving a critical section. */ \ usCriticalNesting--; \ \ /* If the nesting level has reached zero then interrupts should be */ \ /* re-enabled. */ \ if( usCriticalNesting == portNO_CRITICAL_SECTION_NESTING ) \ { \ portENABLE_INTERRUPTS(); \ } \ } \ } /*-----------------------------------------------------------*/ /* Task utilities. */ /* * Manual context switch called by portYIELD or taskYIELD. */ extern void vPortYield( void ); #define portYIELD() vPortYield() /*-----------------------------------------------------------*/ /* Hardware specifics. */ #define portBYTE_ALIGNMENT 2 #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portNOP() __no_operation() /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) #define portYIELD_FROM_ISR( x ) do { if( x ) vPortYield(); } while( 0 ) void vApplicationSetupTimerInterrupt( void ); /* sizeof( int ) != sizeof( long ) so a full printf() library is required if run time stats information is to be displayed. */ #define portLU_PRINTF_SPECIFIER_REQUIRED #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/Keil/See-also-the-RVDS-directory.txt ================================================ Nothing to see here. ================================================ FILE: FreeRTOS-comparison/portable/MemMang/ReadMe.url ================================================ [{000214A0-0000-0000-C000-000000000046}] Prop3=19,2 [InternetShortcut] URL=https://www.FreeRTOS.org/a00111.html IDList= ================================================ FILE: FreeRTOS-comparison/portable/MemMang/heap_1.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* * The simplest possible implementation of pvPortMalloc(). Note that this * implementation does NOT allow allocated memory to be freed again. * * See heap_2.c, heap_3.c and heap_4.c for alternative implementations, and the * memory management pages of https://www.FreeRTOS.org for more information. */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #include "FreeRTOS.h" #include "task.h" #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 #endif /* A few bytes might be lost to byte aligning the heap start address. */ #define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) /* Allocate the memory for the heap. */ #if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) /* The application writer has already defined the array used for the RTOS * heap - probably so it can be placed in a special segment or address. */ extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; #else static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; #endif /* configAPPLICATION_ALLOCATED_HEAP */ /* Index into the ucHeap array. */ static size_t xNextFreeByte = ( size_t ) 0; /*-----------------------------------------------------------*/ void * pvPortMalloc( size_t xWantedSize ) { void * pvReturn = NULL; static uint8_t * pucAlignedHeap = NULL; /* Ensure that blocks are always aligned. */ #if ( portBYTE_ALIGNMENT != 1 ) { if( xWantedSize & portBYTE_ALIGNMENT_MASK ) { /* Byte alignment required. Check for overflow. */ if( ( xWantedSize + ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ) ) > xWantedSize ) { xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); } else { xWantedSize = 0; } } } #endif /* if ( portBYTE_ALIGNMENT != 1 ) */ vTaskSuspendAll(); { if( pucAlignedHeap == NULL ) { /* Ensure the heap starts on a correctly aligned boundary. */ pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) & ucHeap[ portBYTE_ALIGNMENT - 1 ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); } /* Check there is enough room left for the allocation and. */ if( ( xWantedSize > 0 ) && /* valid size */ ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) && ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) ) /* Check for overflow. */ { /* Return the next free byte then increment the index past this * block. */ pvReturn = pucAlignedHeap + xNextFreeByte; xNextFreeByte += xWantedSize; } traceMALLOC( pvReturn, xWantedSize ); } ( void ) xTaskResumeAll(); #if ( configUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { vApplicationMallocFailedHook(); } } #endif return pvReturn; } /*-----------------------------------------------------------*/ void vPortFree( void * pv ) { /* Memory cannot be freed using this scheme. See heap_2.c, heap_3.c and * heap_4.c for alternative implementations, and the memory management pages of * https://www.FreeRTOS.org for more information. */ ( void ) pv; /* Force an assert as it is invalid to call this function. */ configASSERT( pv == NULL ); } /*-----------------------------------------------------------*/ void vPortInitialiseBlocks( void ) { /* Only required when static memory is not cleared. */ xNextFreeByte = ( size_t ) 0; } /*-----------------------------------------------------------*/ size_t xPortGetFreeHeapSize( void ) { return( configADJUSTED_HEAP_SIZE - xNextFreeByte ); } ================================================ FILE: FreeRTOS-comparison/portable/MemMang/heap_2.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* * A sample implementation of pvPortMalloc() and vPortFree() that permits * allocated blocks to be freed, but does not combine adjacent free blocks * into a single larger block (and so will fragment memory). See heap_4.c for * an equivalent that does combine adjacent blocks into single larger blocks. * * See heap_1.c, heap_3.c and heap_4.c for alternative implementations, and the * memory management pages of https://www.FreeRTOS.org for more information. */ #include #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #include "FreeRTOS.h" #include "task.h" #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 #endif #ifndef configHEAP_CLEAR_MEMORY_ON_FREE #define configHEAP_CLEAR_MEMORY_ON_FREE 0 #endif /* A few bytes might be lost to byte aligning the heap start address. */ #define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) /* Assumes 8bit bytes! */ #define heapBITS_PER_BYTE ( ( size_t ) 8 ) /* Max value that fits in a size_t type. */ #define heapSIZE_MAX ( ~( ( size_t ) 0 ) ) /* Check if multiplying a and b will result in overflow. */ #define heapMULTIPLY_WILL_OVERFLOW( a, b ) ( ( ( a ) > 0 ) && ( ( b ) > ( heapSIZE_MAX / ( a ) ) ) ) /* Check if adding a and b will result in overflow. */ #define heapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( heapSIZE_MAX - ( b ) ) ) /* 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 * an BlockLink_t structure is set then the block belongs to the application. * When the bit is free the block is still part of the free heap space. */ #define heapBLOCK_ALLOCATED_BITMASK ( ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ) ) #define heapBLOCK_SIZE_IS_VALID( xBlockSize ) ( ( ( xBlockSize ) & heapBLOCK_ALLOCATED_BITMASK ) == 0 ) #define heapBLOCK_IS_ALLOCATED( pxBlock ) ( ( ( pxBlock->xBlockSize ) & heapBLOCK_ALLOCATED_BITMASK ) != 0 ) #define heapALLOCATE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) |= heapBLOCK_ALLOCATED_BITMASK ) #define heapFREE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) &= ~heapBLOCK_ALLOCATED_BITMASK ) /*-----------------------------------------------------------*/ /* Allocate the memory for the heap. */ #if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) /* The application writer has already defined the array used for the RTOS * heap - probably so it can be placed in a special segment or address. */ extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; #else PRIVILEGED_DATA static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; #endif /* configAPPLICATION_ALLOCATED_HEAP */ /* Define the linked list structure. This is used to link free blocks in order * of their size. */ typedef struct A_BLOCK_LINK { struct A_BLOCK_LINK * pxNextFreeBlock; /*<< The next free block in the list. */ size_t xBlockSize; /*<< The size of the free block. */ } BlockLink_t; static const uint16_t heapSTRUCT_SIZE = ( ( sizeof( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ) ); #define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) /* Create a couple of list links to mark the start and end of the list. */ PRIVILEGED_DATA static BlockLink_t xStart, xEnd; /* Keeps track of the number of free bytes remaining, but says nothing about * fragmentation. */ PRIVILEGED_DATA static size_t xFreeBytesRemaining = configADJUSTED_HEAP_SIZE; /*-----------------------------------------------------------*/ /* * Initialises the heap structures before their first use. */ static void prvHeapInit( void ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */ /* * Insert a block into the list of free blocks - which is ordered by size of * the block. Small blocks at the start of the list and large blocks at the end * of the list. */ #define prvInsertBlockIntoFreeList( pxBlockToInsert ) \ { \ BlockLink_t * pxIterator; \ size_t xBlockSize; \ \ xBlockSize = pxBlockToInsert->xBlockSize; \ \ /* Iterate through the list until a block is found that has a larger size */ \ /* than the block we are inserting. */ \ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \ { \ /* There is nothing to do here - just iterate to the correct position. */ \ } \ \ /* Update the list to include the block being inserted in the correct */ \ /* position. */ \ pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; \ pxIterator->pxNextFreeBlock = pxBlockToInsert; \ } /*-----------------------------------------------------------*/ void * pvPortMalloc( size_t xWantedSize ) { BlockLink_t * pxBlock; BlockLink_t * pxPreviousBlock; BlockLink_t * pxNewBlockLink; PRIVILEGED_DATA static BaseType_t xHeapHasBeenInitialised = pdFALSE; void * pvReturn = NULL; size_t xAdditionalRequiredSize; vTaskSuspendAll(); { /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ if( xHeapHasBeenInitialised == pdFALSE ) { prvHeapInit(); xHeapHasBeenInitialised = pdTRUE; } if( xWantedSize > 0 ) { /* The wanted size must be increased so it can contain a BlockLink_t * structure in addition to the requested amount of bytes. Some * additional increment may also be needed for alignment. */ xAdditionalRequiredSize = heapSTRUCT_SIZE + portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ); if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 ) { xWantedSize += xAdditionalRequiredSize; } else { xWantedSize = 0; } } /* Check the block size we are trying to allocate is not so large that the * top bit is set. The top bit of the block size member of the BlockLink_t * structure is used to determine who owns the block - the application or * the kernel, so it must be free. */ if( heapBLOCK_SIZE_IS_VALID( xWantedSize ) != 0 ) { if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) { /* Blocks are stored in byte order - traverse the list from the start * (smallest) block until one of adequate size is found. */ pxPreviousBlock = &xStart; pxBlock = xStart.pxNextFreeBlock; while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) { pxPreviousBlock = pxBlock; pxBlock = pxBlock->pxNextFreeBlock; } /* If we found the end marker then a block of adequate size was not found. */ if( pxBlock != &xEnd ) { /* Return the memory space - jumping over the BlockLink_t structure * at its start. */ pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); /* This block is being returned for use so must be taken out of the * list of free blocks. */ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; /* If the block is larger than required it can be split into two. */ if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) { /* This block is to be split into two. Create a new block * following the number of bytes requested. The void cast is * used to prevent byte alignment warnings from the compiler. */ pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); /* Calculate the sizes of two blocks split from the single * block. */ pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; pxBlock->xBlockSize = xWantedSize; /* Insert the new block into the list of free blocks. */ prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); } xFreeBytesRemaining -= pxBlock->xBlockSize; /* The block is being returned - it is allocated and owned * by the application and has no "next" block. */ heapALLOCATE_BLOCK( pxBlock ); pxBlock->pxNextFreeBlock = NULL; } } } traceMALLOC( pvReturn, xWantedSize ); } ( void ) xTaskResumeAll(); #if ( configUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { vApplicationMallocFailedHook(); } } #endif return pvReturn; } /*-----------------------------------------------------------*/ void vPortFree( void * pv ) { uint8_t * puc = ( uint8_t * ) pv; BlockLink_t * pxLink; if( pv != NULL ) { /* The memory being freed will have an BlockLink_t structure immediately * before it. */ puc -= heapSTRUCT_SIZE; /* This unexpected casting is to keep some compilers from issuing * byte alignment warnings. */ pxLink = ( void * ) puc; configASSERT( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 ); configASSERT( pxLink->pxNextFreeBlock == NULL ); if( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 ) { if( pxLink->pxNextFreeBlock == NULL ) { /* The block is being returned to the heap - it is no longer * allocated. */ heapFREE_BLOCK( pxLink ); #if ( configHEAP_CLEAR_MEMORY_ON_FREE == 1 ) { ( void ) memset( puc + heapSTRUCT_SIZE, 0, pxLink->xBlockSize - heapSTRUCT_SIZE ); } #endif vTaskSuspendAll(); { /* Add this block to the list of free blocks. */ prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); xFreeBytesRemaining += pxLink->xBlockSize; traceFREE( pv, pxLink->xBlockSize ); } ( void ) xTaskResumeAll(); } } } } /*-----------------------------------------------------------*/ size_t xPortGetFreeHeapSize( void ) { return xFreeBytesRemaining; } /*-----------------------------------------------------------*/ void vPortInitialiseBlocks( void ) { /* This just exists to keep the linker quiet. */ } /*-----------------------------------------------------------*/ void * pvPortCalloc( size_t xNum, size_t xSize ) { void * pv = NULL; if( heapMULTIPLY_WILL_OVERFLOW( xNum, xSize ) == 0 ) { pv = pvPortMalloc( xNum * xSize ); if( pv != NULL ) { ( void ) memset( pv, 0, xNum * xSize ); } } return pv; } /*-----------------------------------------------------------*/ static void prvHeapInit( void ) /* PRIVILEGED_FUNCTION */ { BlockLink_t * pxFirstFreeBlock; uint8_t * pucAlignedHeap; /* Ensure the heap starts on a correctly aligned boundary. */ pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) & ucHeap[ portBYTE_ALIGNMENT - 1 ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); /* xStart is used to hold a pointer to the first item in the list of free * blocks. The void cast is used to prevent compiler warnings. */ xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; xStart.xBlockSize = ( size_t ) 0; /* xEnd is used to mark the end of the list of free blocks. */ xEnd.xBlockSize = configADJUSTED_HEAP_SIZE; xEnd.pxNextFreeBlock = NULL; /* To start with there is a single free block that is sized to take up the * entire heap space. */ pxFirstFreeBlock = ( BlockLink_t * ) pucAlignedHeap; pxFirstFreeBlock->xBlockSize = configADJUSTED_HEAP_SIZE; pxFirstFreeBlock->pxNextFreeBlock = &xEnd; } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/MemMang/heap_3.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* * Implementation of pvPortMalloc() and vPortFree() that relies on the * compilers own malloc() and free() implementations. * * This file can only be used if the linker is configured to to generate * a heap memory area. * * See heap_1.c, heap_2.c and heap_4.c for alternative implementations, and the * memory management pages of https://www.FreeRTOS.org for more information. */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #include "FreeRTOS.h" #include "task.h" #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 #endif /*-----------------------------------------------------------*/ void * pvPortMalloc( size_t xWantedSize ) { void * pvReturn; vTaskSuspendAll(); { pvReturn = malloc( xWantedSize ); traceMALLOC( pvReturn, xWantedSize ); } ( void ) xTaskResumeAll(); #if ( configUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { vApplicationMallocFailedHook(); } } #endif return pvReturn; } /*-----------------------------------------------------------*/ void vPortFree( void * pv ) { if( pv != NULL ) { vTaskSuspendAll(); { free( pv ); traceFREE( pv, 0 ); } ( void ) xTaskResumeAll(); } } ================================================ FILE: FreeRTOS-comparison/portable/MemMang/heap_4.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* * A sample implementation of pvPortMalloc() and vPortFree() that combines * (coalescences) adjacent memory blocks as they are freed, and in so doing * limits memory fragmentation. * * See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the * memory management pages of https://www.FreeRTOS.org for more information. */ #include #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #include "FreeRTOS.h" #include "task.h" #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 #endif #ifndef configHEAP_CLEAR_MEMORY_ON_FREE #define configHEAP_CLEAR_MEMORY_ON_FREE 0 #endif /* Block sizes must not get too small. */ #define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) /* Assumes 8bit bytes! */ #define heapBITS_PER_BYTE ( ( size_t ) 8 ) /* Max value that fits in a size_t type. */ #define heapSIZE_MAX ( ~( ( size_t ) 0 ) ) /* Check if multiplying a and b will result in overflow. */ #define heapMULTIPLY_WILL_OVERFLOW( a, b ) ( ( ( a ) > 0 ) && ( ( b ) > ( heapSIZE_MAX / ( a ) ) ) ) /* Check if adding a and b will result in overflow. */ #define heapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( heapSIZE_MAX - ( b ) ) ) /* 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 * an BlockLink_t structure is set then the block belongs to the application. * When the bit is free the block is still part of the free heap space. */ #define heapBLOCK_ALLOCATED_BITMASK ( ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ) ) #define heapBLOCK_SIZE_IS_VALID( xBlockSize ) ( ( ( xBlockSize ) & heapBLOCK_ALLOCATED_BITMASK ) == 0 ) #define heapBLOCK_IS_ALLOCATED( pxBlock ) ( ( ( pxBlock->xBlockSize ) & heapBLOCK_ALLOCATED_BITMASK ) != 0 ) #define heapALLOCATE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) |= heapBLOCK_ALLOCATED_BITMASK ) #define heapFREE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) &= ~heapBLOCK_ALLOCATED_BITMASK ) /*-----------------------------------------------------------*/ /* Allocate the memory for the heap. */ #if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) /* The application writer has already defined the array used for the RTOS * heap - probably so it can be placed in a special segment or address. */ extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; #else PRIVILEGED_DATA static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; #endif /* configAPPLICATION_ALLOCATED_HEAP */ /* Define the linked list structure. This is used to link free blocks in order * of their memory address. */ typedef struct A_BLOCK_LINK { struct A_BLOCK_LINK * pxNextFreeBlock; /*<< The next free block in the list. */ size_t xBlockSize; /*<< The size of the free block. */ } BlockLink_t; /*-----------------------------------------------------------*/ /* * Inserts a block of memory that is being freed into the correct position in * the list of free memory blocks. The block being freed will be merged with * the block in front it and/or the block behind it if the memory blocks are * adjacent to each other. */ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) PRIVILEGED_FUNCTION; /* * Called automatically to setup the required heap structures the first time * pvPortMalloc() is called. */ static void prvHeapInit( void ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /* The size of the structure placed at the beginning of each allocated memory * block must by correctly byte aligned. */ static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); /* Create a couple of list links to mark the start and end of the list. */ PRIVILEGED_DATA static BlockLink_t xStart; PRIVILEGED_DATA static BlockLink_t * pxEnd = NULL; /* Keeps track of the number of calls to allocate and free memory as well as the * number of free bytes remaining, but says nothing about fragmentation. */ PRIVILEGED_DATA static size_t xFreeBytesRemaining = 0U; PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = 0U; PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = 0; PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = 0; /*-----------------------------------------------------------*/ void * pvPortMalloc( size_t xWantedSize ) { BlockLink_t * pxBlock; BlockLink_t * pxPreviousBlock; BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; size_t xAdditionalRequiredSize; vTaskSuspendAll(); { /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ if( pxEnd == NULL ) { prvHeapInit(); } else { mtCOVERAGE_TEST_MARKER(); } if( xWantedSize > 0 ) { /* The wanted size must be increased so it can contain a BlockLink_t * structure in addition to the requested amount of bytes. Some * additional increment may also be needed for alignment. */ xAdditionalRequiredSize = xHeapStructSize + portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ); if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 ) { xWantedSize += xAdditionalRequiredSize; } else { xWantedSize = 0; } } else { mtCOVERAGE_TEST_MARKER(); } /* Check the block size we are trying to allocate is not so large that the * top bit is set. The top bit of the block size member of the BlockLink_t * structure is used to determine who owns the block - the application or * the kernel, so it must be free. */ if( heapBLOCK_SIZE_IS_VALID( xWantedSize ) != 0 ) { if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) { /* Traverse the list from the start (lowest address) block until * one of adequate size is found. */ pxPreviousBlock = &xStart; pxBlock = xStart.pxNextFreeBlock; while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) { pxPreviousBlock = pxBlock; pxBlock = pxBlock->pxNextFreeBlock; } /* If the end marker was reached then a block of adequate size * was not found. */ if( pxBlock != pxEnd ) { /* Return the memory space pointed to - jumping over the * BlockLink_t structure at its start. */ pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); /* This block is being returned for use so must be taken out * of the list of free blocks. */ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; /* If the block is larger than required it can be split into * two. */ if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) { /* This block is to be split into two. Create a new * block following the number of bytes requested. The void * cast is used to prevent byte alignment warnings from the * compiler. */ pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 ); /* Calculate the sizes of two blocks split from the * single block. */ pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; pxBlock->xBlockSize = xWantedSize; /* Insert the new block into the list of free blocks. */ prvInsertBlockIntoFreeList( pxNewBlockLink ); } else { mtCOVERAGE_TEST_MARKER(); } xFreeBytesRemaining -= pxBlock->xBlockSize; if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) { xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; } else { mtCOVERAGE_TEST_MARKER(); } /* The block is being returned - it is allocated and owned * by the application and has no "next" block. */ heapALLOCATE_BLOCK( pxBlock ); pxBlock->pxNextFreeBlock = NULL; xNumberOfSuccessfulAllocations++; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } traceMALLOC( pvReturn, xWantedSize ); } ( void ) xTaskResumeAll(); #if ( configUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { vApplicationMallocFailedHook(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* if ( configUSE_MALLOC_FAILED_HOOK == 1 ) */ configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 ); return pvReturn; } /*-----------------------------------------------------------*/ void vPortFree( void * pv ) { uint8_t * puc = ( uint8_t * ) pv; BlockLink_t * pxLink; if( pv != NULL ) { /* The memory being freed will have an BlockLink_t structure immediately * before it. */ puc -= xHeapStructSize; /* This casting is to keep the compiler from issuing warnings. */ pxLink = ( void * ) puc; configASSERT( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 ); configASSERT( pxLink->pxNextFreeBlock == NULL ); if( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 ) { if( pxLink->pxNextFreeBlock == NULL ) { /* The block is being returned to the heap - it is no longer * allocated. */ heapFREE_BLOCK( pxLink ); #if ( configHEAP_CLEAR_MEMORY_ON_FREE == 1 ) { ( void ) memset( puc + xHeapStructSize, 0, pxLink->xBlockSize - xHeapStructSize ); } #endif vTaskSuspendAll(); { /* Add this block to the list of free blocks. */ xFreeBytesRemaining += pxLink->xBlockSize; traceFREE( pv, pxLink->xBlockSize ); prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); xNumberOfSuccessfulFrees++; } ( void ) xTaskResumeAll(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } } /*-----------------------------------------------------------*/ size_t xPortGetFreeHeapSize( void ) { return xFreeBytesRemaining; } /*-----------------------------------------------------------*/ size_t xPortGetMinimumEverFreeHeapSize( void ) { return xMinimumEverFreeBytesRemaining; } /*-----------------------------------------------------------*/ void vPortInitialiseBlocks( void ) { /* This just exists to keep the linker quiet. */ } /*-----------------------------------------------------------*/ void * pvPortCalloc( size_t xNum, size_t xSize ) { void * pv = NULL; if( heapMULTIPLY_WILL_OVERFLOW( xNum, xSize ) == 0 ) { pv = pvPortMalloc( xNum * xSize ); if( pv != NULL ) { ( void ) memset( pv, 0, xNum * xSize ); } } return pv; } /*-----------------------------------------------------------*/ static void prvHeapInit( void ) /* PRIVILEGED_FUNCTION */ { BlockLink_t * pxFirstFreeBlock; uint8_t * pucAlignedHeap; portPOINTER_SIZE_TYPE uxAddress; size_t xTotalHeapSize = configTOTAL_HEAP_SIZE; /* Ensure the heap starts on a correctly aligned boundary. */ uxAddress = ( portPOINTER_SIZE_TYPE ) ucHeap; if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) { uxAddress += ( portBYTE_ALIGNMENT - 1 ); uxAddress &= ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ); xTotalHeapSize -= uxAddress - ( portPOINTER_SIZE_TYPE ) ucHeap; } pucAlignedHeap = ( uint8_t * ) uxAddress; /* xStart is used to hold a pointer to the first item in the list of free * blocks. The void cast is used to prevent compiler warnings. */ xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; xStart.xBlockSize = ( size_t ) 0; /* pxEnd is used to mark the end of the list of free blocks and is inserted * at the end of the heap space. */ uxAddress = ( ( portPOINTER_SIZE_TYPE ) pucAlignedHeap ) + xTotalHeapSize; uxAddress -= xHeapStructSize; uxAddress &= ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ); pxEnd = ( BlockLink_t * ) uxAddress; pxEnd->xBlockSize = 0; pxEnd->pxNextFreeBlock = NULL; /* To start with there is a single free block that is sized to take up the * entire heap space, minus the space taken by pxEnd. */ pxFirstFreeBlock = ( BlockLink_t * ) pucAlignedHeap; pxFirstFreeBlock->xBlockSize = ( size_t ) ( uxAddress - ( portPOINTER_SIZE_TYPE ) pxFirstFreeBlock ); pxFirstFreeBlock->pxNextFreeBlock = pxEnd; /* Only one block exists - and it covers the entire usable heap space. */ xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; } /*-----------------------------------------------------------*/ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) /* PRIVILEGED_FUNCTION */ { BlockLink_t * pxIterator; uint8_t * puc; /* Iterate through the list until a block is found that has a higher address * than the block being inserted. */ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) { /* Nothing to do here, just iterate to the right position. */ } /* Do the block being inserted, and the block it is being inserted after * make a contiguous block of memory? */ puc = ( uint8_t * ) pxIterator; if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) { pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; pxBlockToInsert = pxIterator; } else { mtCOVERAGE_TEST_MARKER(); } /* Do the block being inserted, and the block it is being inserted before * make a contiguous block of memory? */ puc = ( uint8_t * ) pxBlockToInsert; if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) { if( pxIterator->pxNextFreeBlock != pxEnd ) { /* Form one big block from the two blocks. */ pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; } else { pxBlockToInsert->pxNextFreeBlock = pxEnd; } } else { pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } /* If the block being inserted plugged a gab, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ if( pxIterator != pxBlockToInsert ) { pxIterator->pxNextFreeBlock = pxBlockToInsert; } else { mtCOVERAGE_TEST_MARKER(); } } /*-----------------------------------------------------------*/ void vPortGetHeapStats( HeapStats_t * pxHeapStats ) { BlockLink_t * pxBlock; size_t xBlocks = 0, xMaxSize = 0, xMinSize = portMAX_DELAY; /* portMAX_DELAY used as a portable way of getting the maximum value. */ vTaskSuspendAll(); { pxBlock = xStart.pxNextFreeBlock; /* pxBlock will be NULL if the heap has not been initialised. The heap * is initialised automatically when the first allocation is made. */ if( pxBlock != NULL ) { while( pxBlock != pxEnd ) { /* Increment the number of blocks and record the largest block seen * so far. */ xBlocks++; if( pxBlock->xBlockSize > xMaxSize ) { xMaxSize = pxBlock->xBlockSize; } if( pxBlock->xBlockSize < xMinSize ) { xMinSize = pxBlock->xBlockSize; } /* Move to the next block in the chain until the last block is * reached. */ pxBlock = pxBlock->pxNextFreeBlock; } } } ( void ) xTaskResumeAll(); pxHeapStats->xSizeOfLargestFreeBlockInBytes = xMaxSize; pxHeapStats->xSizeOfSmallestFreeBlockInBytes = xMinSize; pxHeapStats->xNumberOfFreeBlocks = xBlocks; taskENTER_CRITICAL(); { pxHeapStats->xAvailableHeapSpaceInBytes = xFreeBytesRemaining; pxHeapStats->xNumberOfSuccessfulAllocations = xNumberOfSuccessfulAllocations; pxHeapStats->xNumberOfSuccessfulFrees = xNumberOfSuccessfulFrees; pxHeapStats->xMinimumEverFreeBytesRemaining = xMinimumEverFreeBytesRemaining; } taskEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/MemMang/heap_5.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* * A sample implementation of pvPortMalloc() that allows the heap to be defined * across multiple non-contigous blocks and combines (coalescences) adjacent * memory blocks as they are freed. * * See heap_1.c, heap_2.c, heap_3.c and heap_4.c for alternative * implementations, and the memory management pages of https://www.FreeRTOS.org * for more information. * * Usage notes: * * vPortDefineHeapRegions() ***must*** be called before pvPortMalloc(). * pvPortMalloc() will be called if any task objects (tasks, queues, event * groups, etc.) are created, therefore vPortDefineHeapRegions() ***must*** be * called before any other objects are defined. * * vPortDefineHeapRegions() takes a single parameter. The parameter is an array * of HeapRegion_t structures. HeapRegion_t is defined in portable.h as * * typedef struct HeapRegion * { * uint8_t *pucStartAddress; << Start address of a block of memory that will be part of the heap. * size_t xSizeInBytes; << Size of the block of memory. * } HeapRegion_t; * * The array is terminated using a NULL zero sized region definition, and the * memory regions defined in the array ***must*** appear in address order from * low address to high address. So the following is a valid example of how * to use the function. * * HeapRegion_t xHeapRegions[] = * { * { ( uint8_t * ) 0x80000000UL, 0x10000 }, << Defines a block of 0x10000 bytes starting at address 0x80000000 * { ( uint8_t * ) 0x90000000UL, 0xa0000 }, << Defines a block of 0xa0000 bytes starting at address of 0x90000000 * { NULL, 0 } << Terminates the array. * }; * * vPortDefineHeapRegions( xHeapRegions ); << Pass the array into vPortDefineHeapRegions(). * * Note 0x80000000 is the lower address so appears in the array first. * */ #include #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #include "FreeRTOS.h" #include "task.h" #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 #endif #ifndef configHEAP_CLEAR_MEMORY_ON_FREE #define configHEAP_CLEAR_MEMORY_ON_FREE 0 #endif /* Block sizes must not get too small. */ #define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) /* Assumes 8bit bytes! */ #define heapBITS_PER_BYTE ( ( size_t ) 8 ) /* Max value that fits in a size_t type. */ #define heapSIZE_MAX ( ~( ( size_t ) 0 ) ) /* Check if multiplying a and b will result in overflow. */ #define heapMULTIPLY_WILL_OVERFLOW( a, b ) ( ( ( a ) > 0 ) && ( ( b ) > ( heapSIZE_MAX / ( a ) ) ) ) /* Check if adding a and b will result in overflow. */ #define heapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( heapSIZE_MAX - ( b ) ) ) /* 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 * an BlockLink_t structure is set then the block belongs to the application. * When the bit is free the block is still part of the free heap space. */ #define heapBLOCK_ALLOCATED_BITMASK ( ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ) ) #define heapBLOCK_SIZE_IS_VALID( xBlockSize ) ( ( ( xBlockSize ) & heapBLOCK_ALLOCATED_BITMASK ) == 0 ) #define heapBLOCK_IS_ALLOCATED( pxBlock ) ( ( ( pxBlock->xBlockSize ) & heapBLOCK_ALLOCATED_BITMASK ) != 0 ) #define heapALLOCATE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) |= heapBLOCK_ALLOCATED_BITMASK ) #define heapFREE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) &= ~heapBLOCK_ALLOCATED_BITMASK ) /*-----------------------------------------------------------*/ /* Define the linked list structure. This is used to link free blocks in order * of their memory address. */ typedef struct A_BLOCK_LINK { struct A_BLOCK_LINK * pxNextFreeBlock; /*<< The next free block in the list. */ size_t xBlockSize; /*<< The size of the free block. */ } BlockLink_t; /*-----------------------------------------------------------*/ /* * Inserts a block of memory that is being freed into the correct position in * the list of free memory blocks. The block being freed will be merged with * the block in front it and/or the block behind it if the memory blocks are * adjacent to each other. */ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ); /*-----------------------------------------------------------*/ /* The size of the structure placed at the beginning of each allocated memory * block must by correctly byte aligned. */ static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); /* Create a couple of list links to mark the start and end of the list. */ static BlockLink_t xStart; static BlockLink_t * pxEnd = NULL; /* Keeps track of the number of calls to allocate and free memory as well as the * number of free bytes remaining, but says nothing about fragmentation. */ static size_t xFreeBytesRemaining = 0U; static size_t xMinimumEverFreeBytesRemaining = 0U; static size_t xNumberOfSuccessfulAllocations = 0; static size_t xNumberOfSuccessfulFrees = 0; /*-----------------------------------------------------------*/ void * pvPortMalloc( size_t xWantedSize ) { BlockLink_t * pxBlock; BlockLink_t * pxPreviousBlock; BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; size_t xAdditionalRequiredSize; /* The heap must be initialised before the first call to * prvPortMalloc(). */ configASSERT( pxEnd ); vTaskSuspendAll(); { if( xWantedSize > 0 ) { /* The wanted size must be increased so it can contain a BlockLink_t * structure in addition to the requested amount of bytes. Some * additional increment may also be needed for alignment. */ xAdditionalRequiredSize = xHeapStructSize + portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ); if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 ) { xWantedSize += xAdditionalRequiredSize; } else { xWantedSize = 0; } } else { mtCOVERAGE_TEST_MARKER(); } /* Check the block size we are trying to allocate is not so large that the * top bit is set. The top bit of the block size member of the BlockLink_t * structure is used to determine who owns the block - the application or * the kernel, so it must be free. */ if( heapBLOCK_SIZE_IS_VALID( xWantedSize ) != 0 ) { if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) { /* Traverse the list from the start (lowest address) block until * one of adequate size is found. */ pxPreviousBlock = &xStart; pxBlock = xStart.pxNextFreeBlock; while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) { pxPreviousBlock = pxBlock; pxBlock = pxBlock->pxNextFreeBlock; } /* If the end marker was reached then a block of adequate size * was not found. */ if( pxBlock != pxEnd ) { /* Return the memory space pointed to - jumping over the * BlockLink_t structure at its start. */ pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); /* This block is being returned for use so must be taken out * of the list of free blocks. */ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; /* If the block is larger than required it can be split into * two. */ if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) { /* This block is to be split into two. Create a new * block following the number of bytes requested. The void * cast is used to prevent byte alignment warnings from the * compiler. */ pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); /* Calculate the sizes of two blocks split from the * single block. */ pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; pxBlock->xBlockSize = xWantedSize; /* Insert the new block into the list of free blocks. */ prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); } else { mtCOVERAGE_TEST_MARKER(); } xFreeBytesRemaining -= pxBlock->xBlockSize; if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) { xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; } else { mtCOVERAGE_TEST_MARKER(); } /* The block is being returned - it is allocated and owned * by the application and has no "next" block. */ heapALLOCATE_BLOCK( pxBlock ); pxBlock->pxNextFreeBlock = NULL; xNumberOfSuccessfulAllocations++; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } traceMALLOC( pvReturn, xWantedSize ); } ( void ) xTaskResumeAll(); #if ( configUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { vApplicationMallocFailedHook(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* if ( configUSE_MALLOC_FAILED_HOOK == 1 ) */ return pvReturn; } /*-----------------------------------------------------------*/ void vPortFree( void * pv ) { uint8_t * puc = ( uint8_t * ) pv; BlockLink_t * pxLink; if( pv != NULL ) { /* The memory being freed will have an BlockLink_t structure immediately * before it. */ puc -= xHeapStructSize; /* This casting is to keep the compiler from issuing warnings. */ pxLink = ( void * ) puc; configASSERT( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 ); configASSERT( pxLink->pxNextFreeBlock == NULL ); if( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 ) { if( pxLink->pxNextFreeBlock == NULL ) { /* The block is being returned to the heap - it is no longer * allocated. */ heapFREE_BLOCK( pxLink ); #if ( configHEAP_CLEAR_MEMORY_ON_FREE == 1 ) { ( void ) memset( puc + xHeapStructSize, 0, pxLink->xBlockSize - xHeapStructSize ); } #endif vTaskSuspendAll(); { /* Add this block to the list of free blocks. */ xFreeBytesRemaining += pxLink->xBlockSize; traceFREE( pv, pxLink->xBlockSize ); prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); xNumberOfSuccessfulFrees++; } ( void ) xTaskResumeAll(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } } /*-----------------------------------------------------------*/ size_t xPortGetFreeHeapSize( void ) { return xFreeBytesRemaining; } /*-----------------------------------------------------------*/ size_t xPortGetMinimumEverFreeHeapSize( void ) { return xMinimumEverFreeBytesRemaining; } /*-----------------------------------------------------------*/ void * pvPortCalloc( size_t xNum, size_t xSize ) { void * pv = NULL; if( heapMULTIPLY_WILL_OVERFLOW( xNum, xSize ) == 0 ) { pv = pvPortMalloc( xNum * xSize ); if( pv != NULL ) { ( void ) memset( pv, 0, xNum * xSize ); } } return pv; } /*-----------------------------------------------------------*/ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) { BlockLink_t * pxIterator; uint8_t * puc; /* Iterate through the list until a block is found that has a higher address * than the block being inserted. */ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) { /* Nothing to do here, just iterate to the right position. */ } /* Do the block being inserted, and the block it is being inserted after * make a contiguous block of memory? */ puc = ( uint8_t * ) pxIterator; if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) { pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; pxBlockToInsert = pxIterator; } else { mtCOVERAGE_TEST_MARKER(); } /* Do the block being inserted, and the block it is being inserted before * make a contiguous block of memory? */ puc = ( uint8_t * ) pxBlockToInsert; if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) { if( pxIterator->pxNextFreeBlock != pxEnd ) { /* Form one big block from the two blocks. */ pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; } else { pxBlockToInsert->pxNextFreeBlock = pxEnd; } } else { pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } /* If the block being inserted plugged a gab, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ if( pxIterator != pxBlockToInsert ) { pxIterator->pxNextFreeBlock = pxBlockToInsert; } else { mtCOVERAGE_TEST_MARKER(); } } /*-----------------------------------------------------------*/ void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) { BlockLink_t * pxFirstFreeBlockInRegion = NULL; BlockLink_t * pxPreviousFreeBlock; portPOINTER_SIZE_TYPE xAlignedHeap; size_t xTotalRegionSize, xTotalHeapSize = 0; BaseType_t xDefinedRegions = 0; portPOINTER_SIZE_TYPE xAddress; const HeapRegion_t * pxHeapRegion; /* Can only call once! */ configASSERT( pxEnd == NULL ); pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] ); while( pxHeapRegion->xSizeInBytes > 0 ) { xTotalRegionSize = pxHeapRegion->xSizeInBytes; /* Ensure the heap region starts on a correctly aligned boundary. */ xAddress = ( portPOINTER_SIZE_TYPE ) pxHeapRegion->pucStartAddress; if( ( xAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) { xAddress += ( portBYTE_ALIGNMENT - 1 ); xAddress &= ~portBYTE_ALIGNMENT_MASK; /* Adjust the size for the bytes lost to alignment. */ xTotalRegionSize -= ( size_t ) ( xAddress - ( portPOINTER_SIZE_TYPE ) pxHeapRegion->pucStartAddress ); } xAlignedHeap = xAddress; /* Set xStart if it has not already been set. */ if( xDefinedRegions == 0 ) { /* xStart is used to hold a pointer to the first item in the list of * free blocks. The void cast is used to prevent compiler warnings. */ xStart.pxNextFreeBlock = ( BlockLink_t * ) xAlignedHeap; xStart.xBlockSize = ( size_t ) 0; } else { /* Should only get here if one region has already been added to the * heap. */ configASSERT( pxEnd != NULL ); /* Check blocks are passed in with increasing start addresses. */ configASSERT( xAddress > ( size_t ) pxEnd ); } /* Remember the location of the end marker in the previous region, if * any. */ pxPreviousFreeBlock = pxEnd; /* pxEnd is used to mark the end of the list of free blocks and is * inserted at the end of the region space. */ xAddress = xAlignedHeap + xTotalRegionSize; xAddress -= xHeapStructSize; xAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); pxEnd = ( BlockLink_t * ) xAddress; pxEnd->xBlockSize = 0; pxEnd->pxNextFreeBlock = NULL; /* To start with there is a single free block in this region that is * sized to take up the entire heap region minus the space taken by the * free block structure. */ pxFirstFreeBlockInRegion = ( BlockLink_t * ) xAlignedHeap; pxFirstFreeBlockInRegion->xBlockSize = ( size_t ) ( xAddress - ( portPOINTER_SIZE_TYPE ) pxFirstFreeBlockInRegion ); pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd; /* If this is not the first region that makes up the entire heap space * then link the previous region to this region. */ if( pxPreviousFreeBlock != NULL ) { pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion; } xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize; /* Move onto the next HeapRegion_t structure. */ xDefinedRegions++; pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] ); } xMinimumEverFreeBytesRemaining = xTotalHeapSize; xFreeBytesRemaining = xTotalHeapSize; /* Check something was actually defined before it is accessed. */ configASSERT( xTotalHeapSize ); } /*-----------------------------------------------------------*/ void vPortGetHeapStats( HeapStats_t * pxHeapStats ) { BlockLink_t * pxBlock; size_t xBlocks = 0, xMaxSize = 0, xMinSize = portMAX_DELAY; /* portMAX_DELAY used as a portable way of getting the maximum value. */ vTaskSuspendAll(); { pxBlock = xStart.pxNextFreeBlock; /* pxBlock will be NULL if the heap has not been initialised. The heap * is initialised automatically when the first allocation is made. */ if( pxBlock != NULL ) { while( pxBlock != pxEnd ) { /* Increment the number of blocks and record the largest block seen * so far. */ xBlocks++; if( pxBlock->xBlockSize > xMaxSize ) { xMaxSize = pxBlock->xBlockSize; } /* Heap five will have a zero sized block at the end of each * each region - the block is only used to link to the next * heap region so it not a real block. */ if( pxBlock->xBlockSize != 0 ) { if( pxBlock->xBlockSize < xMinSize ) { xMinSize = pxBlock->xBlockSize; } } /* Move to the next block in the chain until the last block is * reached. */ pxBlock = pxBlock->pxNextFreeBlock; } } } ( void ) xTaskResumeAll(); pxHeapStats->xSizeOfLargestFreeBlockInBytes = xMaxSize; pxHeapStats->xSizeOfSmallestFreeBlockInBytes = xMinSize; pxHeapStats->xNumberOfFreeBlocks = xBlocks; taskENTER_CRITICAL(); { pxHeapStats->xAvailableHeapSpaceInBytes = xFreeBytesRemaining; pxHeapStats->xNumberOfSuccessfulAllocations = xNumberOfSuccessfulAllocations; pxHeapStats->xNumberOfSuccessfulFrees = xNumberOfSuccessfulFrees; pxHeapStats->xMinimumEverFreeBytesRemaining = xMinimumEverFreeBytesRemaining; } taskEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM7_LPC21xx/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* Constants required to setup the initial task context. */ #define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */ #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) #define portINSTRUCTION_SIZE ( ( StackType_t ) 4 ) #define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 ) /* Constants required to setup the tick ISR. */ #define portENABLE_TIMER ( ( uint8_t ) 0x01 ) #define portPRESCALE_VALUE 0x00 #define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 ) #define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 ) /* Constants required to setup the VIC for the tick ISR. */ #define portTIMER_VIC_CHANNEL ( ( uint32_t ) 0x0004 ) #define portTIMER_VIC_CHANNEL_BIT ( ( uint32_t ) 0x0010 ) #define portTIMER_VIC_ENABLE ( ( uint32_t ) 0x0020 ) /* Constants required to handle interrupts. */ #define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 ) #define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 ) /*-----------------------------------------------------------*/ /* The code generated by the Keil compiler does not maintain separate stack and frame pointers. The portENTER_CRITICAL macro cannot therefore use the stack as per other ports. Instead 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 a non zero value. */ #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 ) volatile uint32_t ulCriticalNesting = 9999UL; /*-----------------------------------------------------------*/ /* Setup the timer to generate the tick interrupts. */ static void prvSetupTimerInterrupt( void ); /* * The scheduler can only be started from ARM mode, so * vPortStartFirstSTask() is defined in portISR.c. */ extern __asm void vPortStartFirstTask( void ); /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { StackType_t *pxOriginalTOS; /* Setup the initial stack of the task. The stack is set exactly as expected by the portRESTORE_CONTEXT() macro. Remember where the top of the (simulated) stack is before we place anything on it. */ pxOriginalTOS = pxTopOfStack; /* To ensure asserts in tasks.c don't fail, although in this case the assert is not really required. */ pxTopOfStack--; /* 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 as it would within an IRQ ISR. */ *pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xaaaaaaaa; /* R14 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; /* The last thing onto the stack is the status register, which is set for system mode, with interrupts enabled. */ *pxTopOfStack = ( StackType_t ) portINITIAL_SPSR; if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00UL ) { /* We want the task to start in thumb mode. */ *pxTopOfStack |= portTHUMB_MODE_BIT; } pxTopOfStack--; /* The code generated by the Keil compiler does not maintain separate stack and frame pointers. The portENTER_CRITICAL macro cannot therefore use the stack as per other ports. Instead 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 initially set to zero. */ *pxTopOfStack = portNO_CRITICAL_SECTION_NESTING; return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) { /* Start the timer that generates the tick ISR. */ prvSetupTimerInterrupt(); /* Start the first task. This is done from portISR.c as ARM mode must be used. */ vPortStartFirstTask(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* It is unlikely that the ARM port will require this function as there is nothing to return to. If this is required - stop the tick ISR then return back to main. */ } /*-----------------------------------------------------------*/ #if configUSE_PREEMPTION == 0 /* * The cooperative scheduler requires a normal IRQ service routine to * simply increment the system tick. */ void vNonPreemptiveTick( void ) __irq; void vNonPreemptiveTick( void ) __irq { /* Increment the tick count - this may make a delaying task ready to run - but a context switch is not performed. */ xTaskIncrementTick(); T0IR = portTIMER_MATCH_ISR_BIT; /* Clear the timer event */ VICVectAddr = portCLEAR_VIC_INTERRUPT; /* Acknowledge the Interrupt */ } #else /* ************************************************************************** * The preemptive scheduler ISR is written in assembler and can be found * in the portASM.s file. This will only get used if portUSE_PREEMPTION * is set to 1 in portmacro.h ************************************************************************** */ void vPreemptiveTick( void ); #endif /*-----------------------------------------------------------*/ static void prvSetupTimerInterrupt( void ) { uint32_t ulCompareMatch; /* A 1ms tick does not require the use of the timer prescale. This is defaulted to zero but can be used if necessary. */ T0PR = portPRESCALE_VALUE; /* Calculate the match value required for our wanted tick rate. */ ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ; /* Protect against divide by zero. Using an if() statement still results in a warning - hence the #if. */ #if portPRESCALE_VALUE != 0 { ulCompareMatch /= ( portPRESCALE_VALUE + 1 ); } #endif T0MR0 = ulCompareMatch; /* Generate tick with timer 0 compare match. */ T0MCR = portRESET_COUNT_ON_MATCH | portINTERRUPT_ON_MATCH; /* Setup the VIC for the timer. */ VICIntSelect &= ~( portTIMER_VIC_CHANNEL_BIT ); VICIntEnable |= portTIMER_VIC_CHANNEL_BIT; /* The ISR installed depends on whether the preemptive or cooperative scheduler is being used. */ #if configUSE_PREEMPTION == 1 { VICVectAddr0 = ( uint32_t ) vPreemptiveTick; } #else { VICVectAddr0 = ( uint32_t ) vNonPreemptiveTick; } #endif VICVectCntl0 = portTIMER_VIC_CHANNEL | portTIMER_VIC_ENABLE; /* Start the timer - interrupts are disabled when this function is called so it is okay to do this here. */ T0TCR = portENABLE_TIMER; } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { /* Disable interrupts as per portDISABLE_INTERRUPTS(); */ __disable_irq(); /* Now interrupts are disabled ulCriticalNesting can be accessed directly. Increment ulCriticalNesting to keep a count of how many times portENTER_CRITICAL() has been called. */ ulCriticalNesting++; } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { if( ulCriticalNesting > portNO_CRITICAL_NESTING ) { /* Decrement the nesting count as we are leaving a critical section. */ ulCriticalNesting--; /* If the nesting level has reached zero then interrupts should be re-enabled. */ if( ulCriticalNesting == portNO_CRITICAL_NESTING ) { /* Enable interrupts as per portEXIT_CRITICAL(). */ __enable_irq(); } } } /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM7_LPC21xx/portASM.s ================================================ ;/* ; * FreeRTOS Kernel V10.5.1 ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * this software and associated documentation files (the "Software"), to deal in ; * the Software without restriction, including without limitation the rights to ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * the Software, and to permit persons to whom the Software is furnished to do so, ; * subject to the following conditions: ; * ; * The above copyright notice and this permission notice shall be included in all ; * copies or substantial portions of the Software. ; * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * ; * https://www.FreeRTOS.org ; * https://github.com/FreeRTOS ; * ; */ INCLUDE portmacro.inc IMPORT vTaskSwitchContext IMPORT xTaskIncrementTick EXPORT vPortYieldProcessor EXPORT vPortStartFirstTask EXPORT vPreemptiveTick EXPORT vPortYield VICVECTADDR EQU 0xFFFFF030 T0IR EQU 0xE0004000 T0MATCHBIT EQU 0x00000001 ARM AREA PORT_ASM, CODE, READONLY ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Starting the first task is done by just restoring the context ; setup by pxPortInitialiseStack ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; vPortStartFirstTask PRESERVE8 portRESTORE_CONTEXT vPortYield PRESERVE8 SVC 0 bx lr ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Interrupt service routine for the SWI interrupt. The vector table is ; configured in the startup.s file. ; ; vPortYieldProcessor() is used to manually force a context switch. The ; SWI interrupt is generated by a call to taskYIELD() or portYIELD(). ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; vPortYieldProcessor PRESERVE8 ; 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 ; ISR return code can be used in both cases. ADD LR, LR, #4 ; Perform the context switch. portSAVE_CONTEXT ; Save current task context LDR R0, =vTaskSwitchContext ; Get the address of the context switch function MOV LR, PC ; Store the return address BX R0 ; Call the contedxt switch function portRESTORE_CONTEXT ; restore the context of the selected task ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Interrupt service routine for preemptive scheduler tick timer ; Only used if portUSE_PREEMPTION is set to 1 in portmacro.h ; ; Uses timer 0 of LPC21XX Family ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; vPreemptiveTick PRESERVE8 portSAVE_CONTEXT ; Save the context of the current task. LDR R0, =xTaskIncrementTick ; Increment the tick count. MOV LR, PC ; This may make a delayed task ready BX R0 ; to run. CMP R0, #0 BEQ SkipContextSwitch LDR R0, =vTaskSwitchContext ; Find the highest priority task that MOV LR, PC ; is ready to run. BX R0 SkipContextSwitch MOV R0, #T0MATCHBIT ; Clear the timer event LDR R1, =T0IR STR R0, [R1] LDR R0, =VICVECTADDR ; Acknowledge the interrupt STR R0,[R0] portRESTORE_CONTEXT ; Restore the context of the highest ; priority task that is ready to run. END ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM7_LPC21xx/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #endif /*-----------------------------------------------------------*/ /* Hardware specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Task utilities. */ /*----------------------------------------------------------- * ISR entry and exit macros. These are only required if a task switch * is required from an ISR. *----------------------------------------------------------*/ /* If a switch is required then we just need to call */ /* vTaskSwitchContext() as the context has already been */ /* saved. */ #define portEXIT_SWITCHING_ISR(SwitchRequired) \ { \ extern void vTaskSwitchContext(void); \ \ if(SwitchRequired) \ { \ vTaskSwitchContext(); \ } \ } \ extern void vPortYield( void ); #define portYIELD() vPortYield() /* Critical section management. */ /* ****************************************************************** * We don't need to worry about whether we're in ARM or * THUMB mode with the Keil Real View compiler when enabling * or disabling interrupts as the compiler's intrinsic functions * take care of that for us. ******************************************************************* */ #define portDISABLE_INTERRUPTS() __disable_irq() #define portENABLE_INTERRUPTS() __enable_irq() /*----------------------------------------------------------- * Critical section control * * The code generated by the Keil compiler does not maintain separate * stack and frame pointers. The portENTER_CRITICAL macro cannot therefore * use the stack as per other ports. Instead a variable is used to keep * track of the critical section nesting. This necessitates the use of a * function in place of the macro. *----------------------------------------------------------*/ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); #define portENTER_CRITICAL() vPortEnterCritical(); #define portEXIT_CRITICAL() vPortExitCritical(); /*-----------------------------------------------------------*/ /* Compiler specifics. */ #define inline #define register #define portNOP() __asm{ NOP } /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM7_LPC21xx/portmacro.inc ================================================ ;/* ; * FreeRTOS Kernel V10.5.1 ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * this software and associated documentation files (the "Software"), to deal in ; * the Software without restriction, including without limitation the rights to ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * the Software, and to permit persons to whom the Software is furnished to do so, ; * subject to the following conditions: ; * ; * The above copyright notice and this permission notice shall be included in all ; * copies or substantial portions of the Software. ; * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * ; * https://www.FreeRTOS.org ; * https://github.com/FreeRTOS ; * ; */ IMPORT ulCriticalNesting ; IMPORT pxCurrentTCB ; MACRO portRESTORE_CONTEXT LDR R0, =pxCurrentTCB ; Set the LR to the task stack. The location was... LDR R0, [R0] ; ... stored in pxCurrentTCB LDR LR, [R0] LDR R0, =ulCriticalNesting ; The critical nesting depth is the first item on... LDMFD LR!, {R1} ; ...the stack. Load it into the ulCriticalNesting var. STR R1, [R0] ; LDMFD LR!, {R0} ; Get the SPSR from the stack. MSR SPSR_cxsf, R0 ; LDMFD LR, {R0-R14}^ ; Restore all system mode registers for the task. NOP ; LDR LR, [LR, #+60] ; Restore the return address ; And return - correcting the offset in the LR to obtain ... SUBS PC, LR, #4 ; ...the correct address. MEND ; /**********************************************************************/ MACRO portSAVE_CONTEXT STMDB SP!, {R0} ; Store R0 first as we need to use it. STMDB SP,{SP}^ ; Set R0 to point to the task stack pointer. NOP ; SUB SP, SP, #4 ; LDMIA SP!,{R0} ; STMDB R0!, {LR} ; Push the return address onto the stack. MOV LR, R0 ; Now we have saved LR we can use it instead of R0. LDMIA SP!, {R0} ; Pop R0 so we can save it onto the system mode stack. STMDB LR,{R0-LR}^ ; Push all the system mode registers onto the task stack. NOP ; SUB LR, LR, #60 ; MRS R0, SPSR ; Push the SPSR onto the task stack. STMDB LR!, {R0} ; LDR R0, =ulCriticalNesting ; LDR R0, [R0] ; STMDB LR!, {R0} ; LDR R0, =pxCurrentTCB ; Store the new top of stack for the task. LDR R1, [R0] ; STR LR, [R1] ; MEND END ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM_CA9/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #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 #endif #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 #endif #ifndef configUNIQUE_INTERRUPT_PRIORITIES #error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif #ifndef configSETUP_TICK_INTERRUPT #error configSETUP_TICK_INTERRUPT() must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif /* configSETUP_TICK_INTERRUPT */ #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 #endif #if configMAX_API_CALL_INTERRUPT_PRIORITY == 0 #error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0 #endif #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 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #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. #endif #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /* In case security extensions are implemented. */ #if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) #error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) #endif #ifndef configCLEAR_TICK_INTERRUPT #define configCLEAR_TICK_INTERRUPT() #endif /* The number of bits to shift for an interrupt priority is dependent on the number of bits implemented by the interrupt controller. */ #if configUNIQUE_INTERRUPT_PRIORITIES == 16 #define portPRIORITY_SHIFT 4 #define portMAX_BINARY_POINT_VALUE 3 #elif configUNIQUE_INTERRUPT_PRIORITIES == 32 #define portPRIORITY_SHIFT 3 #define portMAX_BINARY_POINT_VALUE 2 #elif configUNIQUE_INTERRUPT_PRIORITIES == 64 #define portPRIORITY_SHIFT 2 #define portMAX_BINARY_POINT_VALUE 1 #elif configUNIQUE_INTERRUPT_PRIORITIES == 128 #define portPRIORITY_SHIFT 1 #define portMAX_BINARY_POINT_VALUE 0 #elif configUNIQUE_INTERRUPT_PRIORITIES == 256 #define portPRIORITY_SHIFT 0 #define portMAX_BINARY_POINT_VALUE 0 #else #error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware #endif /* A critical section is exited when the critical section nesting count reaches this value. */ #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 ) /* In all GICs 255 can be written to the priority mask register to unmask all (but the lowest) interrupt priority. */ #define portUNMASK_VALUE ( 0xFFUL ) /* 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 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 context. */ #define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 ) /* Interrupt controller access addresses. */ #define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 ) #define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C ) #define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 ) #define portICCBPR_BINARY_POINT_OFFSET ( 0x08 ) #define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 ) #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 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 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 portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) ) /* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary point is zero. */ #define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 ) /* Constants required to setup the initial task context. */ #define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */ #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) #define portTHUMB_MODE_ADDRESS ( 0x01UL ) /* Masks all bits in the APSR other than the mode bits. */ #define portAPSR_MODE_BITS_MASK ( 0x1F ) /* The value of the mode bits in the APSR when the CPU is executing in user mode. */ #define portAPSR_USER_MODE ( 0x10 ) /* Macro to unmask all interrupt priorities. */ #define portCLEAR_INTERRUPT_MASK() \ { \ __disable_irq(); \ portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \ __asm( "DSB \n" \ "ISB \n" ); \ __enable_irq(); \ } /*-----------------------------------------------------------*/ /* * Starts the first task executing. This function is necessarily written in * assembly code so is implemented in portASM.s. */ extern void vPortRestoreTaskContext( void ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* 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 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 automatically be set to 0 when the first task is started. */ volatile uint32_t ulCriticalNesting = 9999UL; /* Used to pass constants into the ASM code. The address at which variables are placed is the constant value so indirect loads in the asm code are not required. */ uint32_t ulICCIAR __attribute__( ( at( portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ) ) ); uint32_t ulICCEOIR __attribute__( ( at( portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ) ) ); uint32_t ulICCPMR __attribute__( ( at( portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ) ) ); uint32_t ulAsmAPIPriorityMask __attribute__( ( at( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ) ); /* 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. */ uint32_t ulPortTaskHasFPUContext = pdFALSE; /* Set to 1 to pend a context switch from an ISR. */ uint32_t ulPortYieldRequired = pdFALSE; /* Counts the interrupt nesting depth. A context switch is only performed if if the nesting depth is 0. */ uint32_t ulPortInterruptNesting = 0UL; /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { /* Setup the initial stack of the task. The stack is set exactly as expected by the portRESTORE_CONTEXT() macro. 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 GDB does not try decoding a non-existent return address. */ *pxTopOfStack = NULL; pxTopOfStack--; *pxTopOfStack = NULL; pxTopOfStack--; *pxTopOfStack = NULL; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portINITIAL_SPSR; if( ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) != 0x00UL ) { /* The task will start in THUMB mode. */ *pxTopOfStack |= portTHUMB_MODE_BIT; } pxTopOfStack--; /* Next the return address, which in this case is the start of the task. */ *pxTopOfStack = ( StackType_t ) pxCode; pxTopOfStack--; /* Next all the registers other than the stack pointer. */ *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* R14 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack--; /* The task will start with a critical nesting count of 0 as interrupts are enabled. */ *pxTopOfStack = portNO_CRITICAL_NESTING; pxTopOfStack--; /* The task will start without a floating point context. A task that uses the floating point hardware must call vPortTaskUsesFPU() before executing any floating point instructions. */ *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to its caller as there is nothing to return to. If a task wants to exit it should instead call vTaskDelete( NULL ). Artificially force an assert() to be triggered if configASSERT() is defined, then stop here so application writers can catch the error. */ configASSERT( ulPortInterruptNesting == ~0UL ); portDISABLE_INTERRUPTS(); for( ;; ); } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) { uint32_t ulAPSR; /* Only continue if the CPU is not in User mode. The CPU must be in a Privileged mode for the scheduler to start. */ __asm( "MRS ulAPSR, APSR" ); ulAPSR &= portAPSR_MODE_BITS_MASK; configASSERT( ulAPSR != portAPSR_USER_MODE ); if( ulAPSR != portAPSR_USER_MODE ) { /* Only continue if the binary point value is set to its lowest possible setting. See the comments in vPortValidateInterruptPriority() below for more information. */ configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ) { /* Start the timer that generates the tick ISR. */ configSETUP_TICK_INTERRUPT(); __enable_irq(); vPortRestoreTaskContext(); } } /* 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 possible value. */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. Artificially force an assert. */ configASSERT( ulCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { /* Disable interrupts as per portDISABLE_INTERRUPTS(); */ ulPortSetInterruptMask(); /* Now interrupts are disabled ulCriticalNesting can be accessed directly. Increment ulCriticalNesting to keep a count of how many times portENTER_CRITICAL() has been called. */ ulCriticalNesting++; /* 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 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 assert function also uses a critical section. */ if( ulCriticalNesting == 1 ) { configASSERT( ulPortInterruptNesting == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { if( ulCriticalNesting > portNO_CRITICAL_NESTING ) { /* Decrement the nesting count as the critical section is being exited. */ ulCriticalNesting--; /* If the nesting level has reached zero then all interrupt priorities must be re-enabled. */ if( ulCriticalNesting == portNO_CRITICAL_NESTING ) { /* Critical nesting has reached zero so all interrupt priorities should be unmasked. */ portCLEAR_INTERRUPT_MASK(); } } } /*-----------------------------------------------------------*/ void FreeRTOS_Tick_Handler( void ) { /* Set interrupt mask before altering scheduler structures. The tick 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. */ __disable_irq(); portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); __asm( "DSB \n" "ISB \n" ); __enable_irq(); /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { ulPortYieldRequired = pdTRUE; } /* Ensure all interrupt priorities are active again. */ portCLEAR_INTERRUPT_MASK(); configCLEAR_TICK_INTERRUPT(); } /*-----------------------------------------------------------*/ void vPortTaskUsesFPU( void ) { uint32_t ulInitialFPSCR = 0; /* 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). */ ulPortTaskHasFPUContext = pdTRUE; /* Initialise the floating point status register. */ __asm( "FMXR FPSCR, ulInitialFPSCR" ); } /*-----------------------------------------------------------*/ void vPortClearInterruptMask( uint32_t ulNewMaskValue ) { if( ulNewMaskValue == pdFALSE ) { portCLEAR_INTERRUPT_MASK(); } } /*-----------------------------------------------------------*/ uint32_t ulPortSetInterruptMask( void ) { uint32_t ulReturn; __disable_irq(); if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ) { /* Interrupts were already masked. */ ulReturn = pdTRUE; } else { ulReturn = pdFALSE; portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); __asm( "DSB \n" "ISB \n" ); } __enable_irq(); return ulReturn; } /*-----------------------------------------------------------*/ #if( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { /* The following assertion will fail if a service routine (ISR) for an interrupt that has been assigned a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API function. ISR safe FreeRTOS API functions must *only* be called from interrupts that have been assigned a priority at or below configMAX_SYSCALL_INTERRUPT_PRIORITY. Numerically low interrupt priority numbers represent logically high interrupt priorities, therefore the priority of the interrupt must be set to a value equal to or numerically *higher* than configMAX_SYSCALL_INTERRUPT_PRIORITY. FreeRTOS maintains separate thread and ISR API functions to ensure interrupt entry is as fast and simple as possible. The following links provide detailed information: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); /* Priority grouping: The interrupt controller (GIC) allows the bits that define each interrupt's priority to be split between bits that define the interrupt's pre-emption priority bits and bits that define the interrupt's sub-priority. For simplicity all bits must be defined to be pre-emption priority bits. The following assertion will fail if this is not the case (if some bits represent a sub-priority). 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 possible value (which may be above 0). */ configASSERT( portICCBPR_BINARY_POINT_REGISTER <= portMAX_BINARY_POINT_VALUE ); } #endif /* configASSERT_DEFINED */ ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM_CA9/portASM.s ================================================ ;/* ; * FreeRTOS Kernel V10.5.1 ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * this software and associated documentation files (the "Software"), to deal in ; * the Software without restriction, including without limitation the rights to ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * the Software, and to permit persons to whom the Software is furnished to do so, ; * subject to the following conditions: ; * ; * The above copyright notice and this permission notice shall be included in all ; * copies or substantial portions of the Software. ; * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * ; * https://www.FreeRTOS.org ; * https://github.com/FreeRTOS ; * ; */ INCLUDE portmacro.inc IMPORT vApplicationIRQHandler IMPORT vTaskSwitchContext IMPORT ulPortYieldRequired IMPORT ulPortInterruptNesting IMPORT vTaskSwitchContext IMPORT ulICCIAR IMPORT ulICCEOIR EXPORT FreeRTOS_SWI_Handler EXPORT FreeRTOS_IRQ_Handler EXPORT vPortRestoreTaskContext ARM AREA PORT_ASM, CODE, READONLY ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SVC handler is used to yield a task. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; FreeRTOS_SWI_Handler PRESERVE8 ; Save the context of the current task and select a new task to run. portSAVE_CONTEXT LDR R0, =vTaskSwitchContext BLX R0 portRESTORE_CONTEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; vPortRestoreTaskContext is used to start the scheduler. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; vPortRestoreTaskContext ; Switch to system mode CPS #SYS_MODE portRESTORE_CONTEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; PL390 GIC interrupt handler ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; FreeRTOS_IRQ_Handler ; Return to the interrupted instruction. SUB lr, lr, #4 ; Push the return address and SPSR PUSH {lr} MRS lr, SPSR PUSH {lr} ; Change to supervisor mode to allow reentry. CPS #SVC_MODE ; Push used registers. PUSH {r0-r4, r12} ; Increment nesting count. r3 holds the address of ulPortInterruptNesting ; for future use. r1 holds the original ulPortInterruptNesting value for ; future use. LDR r3, =ulPortInterruptNesting LDR r1, [r3] ADD r4, r1, #1 STR r4, [r3] ; Read value from the interrupt acknowledge register, which is stored in r0 ; for future parameter and interrupt clearing use. LDR r2, =ulICCIAR LDR r0, [r2] ; Ensure bit 2 of the stack pointer is clear. r2 holds the bit 2 value for ; future use. _RB_ Does this ever actually need to be done provided the ; start of the stack is 8-byte aligned? MOV r2, sp AND r2, r2, #4 SUB sp, sp, r2 ; Call the interrupt handler. r4 is pushed to maintain alignment. PUSH {r0-r4, lr} LDR r1, =vApplicationIRQHandler BLX r1 POP {r0-r4, lr} ADD sp, sp, r2 CPSID i ; Write the value read from ICCIAR to ICCEOIR LDR r4, =ulICCEOIR STR r0, [r4] ; Restore the old nesting count STR r1, [r3] ; A context switch is never performed if the nesting count is not 0 CMP r1, #0 BNE exit_without_switch ; Did the interrupt request a context switch? r1 holds the address of ; ulPortYieldRequired and r0 the value of ulPortYieldRequired for future ; use. LDR r1, =ulPortYieldRequired LDR r0, [r1] CMP r0, #0 BNE switch_before_exit exit_without_switch ; No context switch. Restore used registers, LR_irq and SPSR before ; returning. POP {r0-r4, r12} CPS #IRQ_MODE POP {LR} MSR SPSR_cxsf, LR POP {LR} MOVS PC, LR switch_before_exit ; A context swtich is to be performed. Clear the context switch pending ; flag. MOV r0, #0 STR r0, [r1] ; Restore used registers, LR-irq and SPSR before saving the context ; to the task stack. POP {r0-r4, r12} CPS #IRQ_MODE POP {LR} MSR SPSR_cxsf, LR POP {LR} portSAVE_CONTEXT ; Call the function that selects the new task to execute. ; vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD ; instructions, or 8 byte aligned stack allocated data. LR does not need ; saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. LDR r0, =vTaskSwitchContext BLX r0 ; Restore the context of, and branch to, the task selected to execute next. portRESTORE_CONTEXT END ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM_CA9/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the given hardware * and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* Hardware specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Task utilities. */ /* Called at the end of an ISR that can cause a context switch. */ #define portEND_SWITCHING_ISR( xSwitchRequired )\ { \ extern uint32_t ulPortYieldRequired; \ \ if( xSwitchRequired != pdFALSE ) \ { \ ulPortYieldRequired = pdTRUE; \ } \ } #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD() __asm( "SWI 0" ); /*----------------------------------------------------------- * Critical section control *----------------------------------------------------------*/ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); extern uint32_t ulPortSetInterruptMask( void ); extern void vPortClearInterruptMask( uint32_t ulNewMaskValue ); /* These macros do not globally disable/enable interrupts. They do mask off interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */ #define portENTER_CRITICAL() vPortEnterCritical(); #define portEXIT_CRITICAL() vPortExitCritical(); #define portDISABLE_INTERRUPTS() ulPortSetInterruptMask() #define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 ) #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x) /*-----------------------------------------------------------*/ /* 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 macros is used. */ #define portTASK_FUNCTION_PROTO( 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 handler for whichever peripheral is used to generate the RTOS tick. */ void FreeRTOS_Tick_Handler( void ); /* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() before any floating point instructions are executed. */ void vPortTaskUsesFPU( void ); #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() #define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) #define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL ) /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif #define portNOP() __nop() #ifdef __cplusplus } #endif #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM_CA9/portmacro.inc ================================================ ;/* ; * FreeRTOS Kernel V10.5.1 ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * this software and associated documentation files (the "Software"), to deal in ; * the Software without restriction, including without limitation the rights to ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * the Software, and to permit persons to whom the Software is furnished to do so, ; * subject to the following conditions: ; * ; * The above copyright notice and this permission notice shall be included in all ; * copies or substantial portions of the Software. ; * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * ; * https://www.FreeRTOS.org ; * https://github.com/FreeRTOS ; * ; */ SYS_MODE EQU 0x1f SVC_MODE EQU 0x13 IRQ_MODE EQU 0x12 IMPORT ulCriticalNesting IMPORT pxCurrentTCB IMPORT ulPortTaskHasFPUContext IMPORT ulAsmAPIPriorityMask IMPORT ulICCPMR MACRO portSAVE_CONTEXT ; Save the LR and SPSR onto the system mode stack before switching to ; system mode to save the remaining system mode registers SRSDB sp!, #SYS_MODE CPS #SYS_MODE PUSH {R0-R12, R14} ; Push the critical nesting count LDR R2, =ulCriticalNesting LDR R1, [R2] PUSH {R1} ; Does the task have a floating point context that needs saving? If ; ulPortTaskHasFPUContext is 0 then no. LDR R2, =ulPortTaskHasFPUContext LDR R3, [R2] CMP R3, #0 ; Save the floating point context, if any FMRXNE R1, FPSCR VPUSHNE {D0-D15} VPUSHNE {D16-D31} PUSHNE {R1} ; Save ulPortTaskHasFPUContext itself PUSH {R3} ; Save the stack pointer in the TCB LDR R0, =pxCurrentTCB LDR R1, [R0] STR SP, [R1] MEND ; /**********************************************************************/ MACRO portRESTORE_CONTEXT ; Set the SP to point to the stack of the task being restored. LDR R0, =pxCurrentTCB LDR R1, [R0] LDR SP, [R1] ; Is there a floating point context to restore? If the restored ; ulPortTaskHasFPUContext is zero then no. LDR R0, =ulPortTaskHasFPUContext POP {R1} STR R1, [R0] CMP R1, #0 ; Restore the floating point context, if any POPNE {R0} VPOPNE {D16-D31} VPOPNE {D0-D15} VMSRNE FPSCR, R0 ; Restore the critical section nesting depth LDR R0, =ulCriticalNesting POP {R1} STR R1, [R0] ; Ensure the priority mask is correct for the critical nesting depth LDR R2, =ulICCPMR CMP R1, #0 MOVEQ R4, #255 LDRNE R4, =ulAsmAPIPriorityMask STR R4, [r2] ; Restore all system mode registers other than the SP (which is already ; being used) POP {R0-R12, R14} ; Return to the task code, loading CPSR on the way. RFEIA sp! MEND END ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM_CM0/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM0 port. *----------------------------------------------------------*/ /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" /* Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) /* The systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /* A fiddle factor to estimate the number of SysTick counts that would have * occurred while the SysTick counter is stopped during tickless idle * calculations. */ #ifndef portMISSED_COUNTS_FACTOR #define portMISSED_COUNTS_FACTOR ( 94UL ) #endif /* Constants used with memory barrier intrinsics. */ #define portSY_FULL_READ_WRITE ( 15 ) /* Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /* Legacy macro for backward compatibility only. This macro used to be used to * replace the function that configures the clock used to generate the tick * interrupt (prvSetupTimerInterrupt()), but now the function is declared weak so * the application writer can override it by simply defining a function of the * same name (vApplicationSetupTickInterrupt()). */ #ifndef configOVERRIDE_DEFAULT_TICK_CONFIGURATION #define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0 #endif /* Each task maintains its own interrupt status in the critical nesting * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* The number of SysTick increments that make up one tick period. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulTimerCountsForOneTick = 0; #endif /* configUSE_TICKLESS_IDLE */ /* The maximum number of tick periods that can be suppressed is limited by the * 24 bit resolution of the SysTick timer. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t xMaximumPossibleSuppressedTicks = 0; #endif /* configUSE_TICKLESS_IDLE */ /* Compensate for the CPU cycles that pass while the SysTick is stopped (low * power functionality only. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ); /* * Exception handlers. */ void xPortPendSVHandler( void ); void xPortSysTickHandler( void ); void vPortSVCHandler( void ); /* * Start first task is a separate function so it can be tested in isolation. */ static void prvPortStartFirstTask( void ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 8; /* R11..R4. */ return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). * * Artificially force an assert() to be triggered if configASSERT() is * defined, then stop here so application writers can catch the error. */ configASSERT( uxCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); for( ; ; ) { } } /*-----------------------------------------------------------*/ void vPortSVCHandler( void ) { /* This function is no longer used, but retained for backward * compatibility. */ } /*-----------------------------------------------------------*/ __asm void prvPortStartFirstTask( void ) { extern pxCurrentTCB; PRESERVE8 /* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector * table offset register that can be used to locate the initial stack value. * Not all M0 parts have the application vector table at address 0. */ /* *INDENT-OFF* */ ldr r3, = pxCurrentTCB /* Obtain location of pxCurrentTCB. */ ldr r1, [ r3 ] ldr r0, [ r1 ] /* The first item in pxCurrentTCB is the task top of stack. */ adds r0, # 32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ movs r0, # 2 /* Switch to the psp stack. */ msr CONTROL, r0 isb pop { r0 - r5 } /* Pop the registers that are saved automatically. */ mov lr, r5 /* lr is now in r5. */ pop { r3 } /* The return address is now in r3. */ pop { r2 } /* Pop and discard the XPSR. */ cpsie i /* The first task has its context and interrupts can be enabled. */ bx r3 /* Finally, jump to the user defined task code. */ ALIGN /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { /* Make PendSV, CallSV and SysTick the same priority as the kernel. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Start the first task. */ prvPortStartFirstTask(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortYield( void ) { /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required but do ensure the code is completely * within the specified behaviour for the architecture. */ __dsb( portSY_FULL_READ_WRITE ); __isb( portSY_FULL_READ_WRITE ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); uxCriticalNesting++; __dsb( portSY_FULL_READ_WRITE ); __isb( portSY_FULL_READ_WRITE ); } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ __asm uint32_t ulSetInterruptMaskFromISR( void ) { /* *INDENT-OFF* */ mrs r0, PRIMASK cpsid i bx lr /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ __asm void vClearInterruptMaskFromISR( uint32_t ulMask ) { /* *INDENT-OFF* */ msr PRIMASK, r0 bx lr /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ __asm void xPortPendSVHandler( void ) { extern vTaskSwitchContext extern pxCurrentTCB /* *INDENT-OFF* */ PRESERVE8 mrs r0, psp ldr r3, = pxCurrentTCB /* Get the location of the current TCB. */ ldr r2, [ r3 ] subs r0, # 32 /* Make space for the remaining low registers. */ str r0, [ r2 ] /* Save the new top of stack. */ stmia r0 !, { r4 - r7 } /* Store the low registers that are not saved automatically. */ mov r4, r8 /* Store the high registers. */ mov r5, r9 mov r6, r10 mov r7, r11 stmia r0 !, { r4 - r7 } push { r3, r14 } cpsid i bl vTaskSwitchContext cpsie i pop { r2, r3 } /* lr goes in r3. r2 now holds tcb pointer. */ ldr r1, [ r2 ] ldr r0, [ r1 ] /* The first item in pxCurrentTCB is the task top of stack. */ adds r0, # 16 /* Move to the high registers. */ ldmia r0 !, { r4 - r7 } /* Pop the high registers. */ mov r8, r4 mov r9, r5 mov r10, r6 mov r11, r7 msr psp, r0 /* Remember the new top of stack for the task. */ subs r0, # 32 /* Go back for the low registers that are not automatically restored. */ ldmia r0 !, { r4 - r7 } /* Pop low registers. */ bx r3 ALIGN /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { uint32_t ulPreviousMask; ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); } /*-----------------------------------------------------------*/ /* * Setup the systick timer to generate the tick interrupts at the required * frequency. */ #if ( configOVERRIDE_DEFAULT_TICK_CONFIGURATION == 0 ) __weak void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and clear the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); } #endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __weak void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __disable_irq(); __dsb( portSY_FULL_READ_WRITE ); __isb( portSY_FULL_READ_WRITE ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the __disable_irq() * call above. */ __enable_irq(); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __dsb( portSY_FULL_READ_WRITE ); __wfi(); __isb( portSY_FULL_READ_WRITE ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the __disable_irq() call above. */ __enable_irq(); __dsb( portSY_FULL_READ_WRITE ); __isb( portSY_FULL_READ_WRITE ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __disable_irq(); __dsb( portSY_FULL_READ_WRITE ); __isb( portSY_FULL_READ_WRITE ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __enable_irq(); } } #endif /* #if configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM_CM0/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /*-----------------------------------------------------------*/ /* Scheduler utilities. */ extern void vPortYield( void ); #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portYIELD() vPortYield() #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); extern uint32_t ulSetInterruptMaskFromISR( void ); extern void vClearInterruptMaskFromISR( uint32_t ulMask ); #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x ) #define portDISABLE_INTERRUPTS() __disable_irq() #define portENABLE_INTERRUPTS() __enable_irq() #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portNOP() /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM_CM3/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM3 port. *----------------------------------------------------------*/ /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #ifndef configKERNEL_INTERRUPT_PRIORITY #define configKERNEL_INTERRUPT_PRIORITY 255 #endif #if configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ #endif /* Legacy macro for backward compatibility only. This macro used to be used to * replace the function that configures the clock used to generate the tick * interrupt (prvSetupTimerInterrupt()), but now the function is declared weak so * the application writer can override it by simply defining a function of the * same name (vApplicationSetupTickInterrupt()). */ #ifndef configOVERRIDE_DEFAULT_TICK_CONFIGURATION #define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0 #endif /* Constants required to manipulate the core. Registers first... */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) /* ...then bits in the registers. */ #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) #define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) ) #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ #define portVECTACTIVE_MASK ( 0xFFUL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) /* The systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /* A fiddle factor to estimate the number of SysTick counts that would have * occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) /* Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ); /* * Exception handlers. */ void xPortPendSVHandler( void ); void xPortSysTickHandler( void ); void vPortSVCHandler( void ); /* * Start first task is a separate function so it can be tested in isolation. */ static void prvStartFirstTask( void ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* Each task maintains its own interrupt status in the critical nesting * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* * The number of SysTick increments that make up one tick period. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulTimerCountsForOneTick = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * The maximum number of tick periods that can be suppressed is limited by the * 24 bit resolution of the SysTick timer. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t xMaximumPossibleSuppressedTicks = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Compensate for the CPU cycles that pass while the SysTick is stopped (low * power functionality only. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. */ #if ( configASSERT_DEFINED == 1 ) static uint8_t ucMaxSysCallPriority = 0; static uint32_t ulMaxPRIGROUPValue = 0; static const volatile uint8_t * const pcInterruptPriorityRegisters = ( uint8_t * ) portNVIC_IP_REGISTERS_OFFSET_16; #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). * * Artificially force an assert() to be triggered if configASSERT() is * defined, then stop here so application writers can catch the error. */ configASSERT( uxCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); for( ; ; ) { } } /*-----------------------------------------------------------*/ __asm void vPortSVCHandler( void ) { /* *INDENT-OFF* */ PRESERVE8 ldr r3, = pxCurrentTCB /* Restore the context. */ ldr r1, [ r3 ] /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ ldr r0, [ r1 ] /* The first item in pxCurrentTCB is the task top of stack. */ ldmia r0 !, { r4 - r11 } /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ msr psp, r0 /* Restore the task stack pointer. */ isb mov r0, # 0 msr basepri, r0 orr r14, # 0xd bx r14 /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ __asm void prvStartFirstTask( void ) { /* *INDENT-OFF* */ PRESERVE8 /* Use the NVIC offset register to locate the stack. */ ldr r0, =0xE000ED08 ldr r0, [ r0 ] ldr r0, [ r0 ] /* Set the msp back to the start of the stack. */ msr msp, r0 /* Globally enable interrupts. */ cpsie i cpsie f dsb isb /* Call SVC to start the first task. */ svc 0 nop nop /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API * functions can be called. ISR safe functions are those that end in * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* The kernel interrupt priority should be set to the lowest * priority. */ configASSERT( ucMaxPriorityValue == ( configKERNEL_INTERRUPT_PRIORITY & ucMaxPriorityValue ) ); /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { ulMaxPRIGROUPValue--; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); } #endif /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; /* Restore the clobbered interrupt priority register to its original * value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Start the first task. */ prvStartFirstTask(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); uxCriticalNesting++; /* 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 * 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 * assert function also uses a critical section. */ if( uxCriticalNesting == 1 ) { configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ __asm void xPortPendSVHandler( void ) { extern uxCriticalNesting; extern pxCurrentTCB; extern vTaskSwitchContext; /* *INDENT-OFF* */ PRESERVE8 mrs r0, psp isb ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */ ldr r2, [ r3 ] stmdb r0 !, { r4 - r11 } /* Save the remaining registers. */ str r0, [ r2 ] /* Save the new top of stack into the first member of the TCB. */ stmdb sp !, { r3, r14 } mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r0 dsb isb bl vTaskSwitchContext mov r0, #0 msr basepri, r0 ldmia sp !, { r3, r14 } ldr r1, [ r3 ] ldr r0, [ r1 ] /* The first item in pxCurrentTCB is the task top of stack. */ ldmia r0 !, { r4 - r11 } /* Pop the registers and the critical nesting count. */ msr psp, r0 isb bx r14 nop /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { /* The SysTick runs at the lowest interrupt priority, so when this interrupt * executes all interrupts must be unmasked. There is therefore no need to * save and then restore the interrupt mask value as its value is already * known - therefore the slightly faster vPortRaiseBASEPRI() function is used * in place of portSET_INTERRUPT_MASK_FROM_ISR(). */ vPortRaiseBASEPRI(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* A context switch is required. Context switching is performed in * the PendSV interrupt. Pend the PendSV interrupt. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } vPortClearBASEPRIFromISR(); } /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __weak void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __disable_irq(); __dsb( portSY_FULL_READ_WRITE ); __isb( portSY_FULL_READ_WRITE ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the __disable_irq() * call above. */ __enable_irq(); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __dsb( portSY_FULL_READ_WRITE ); __wfi(); __isb( portSY_FULL_READ_WRITE ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the __disable_irq() call above. */ __enable_irq(); __dsb( portSY_FULL_READ_WRITE ); __isb( portSY_FULL_READ_WRITE ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __disable_irq(); __dsb( portSY_FULL_READ_WRITE ); __isb( portSY_FULL_READ_WRITE ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __enable_irq(); } } #endif /* #if configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ /* * Setup the SysTick timer to generate the tick interrupts at the required * frequency. */ #if ( configOVERRIDE_DEFAULT_TICK_CONFIGURATION == 0 ) __weak void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and clear the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); } #endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */ /*-----------------------------------------------------------*/ __asm uint32_t vPortGetIPSR( void ) { /* *INDENT-OFF* */ PRESERVE8 mrs r0, ipsr bx r14 /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; /* Obtain the number of the currently executing interrupt. */ ulCurrentInterrupt = vPortGetIPSR(); /* Is the interrupt number a user defined interrupt? */ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /* Look up the interrupt's priority. */ ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Interrupts that use the FreeRTOS API must not be left at their * default priority of zero as that is the highest possible priority, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * and therefore also guaranteed to be invalid. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } /* Priority grouping: The interrupt controller (NVIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined * to be pre-emption priority bits. The following assertion will fail if * this is not the case (if some bits represent a sub-priority). * * If the application only uses CMSIS libraries for interrupt * configuration then the correct setting can be achieved on all Cortex-M * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * scheduler. Note however that some vendor specific peripheral libraries * assume a non-zero priority group setting, in which cases using a value * of zero will result in unpredictable behaviour. */ configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); } #endif /* configASSERT_DEFINED */ ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM_CM3/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /* Constants used with memory barrier intrinsics. */ #define portSY_FULL_READ_WRITE ( 15 ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ #define portYIELD() \ { \ /* Set a PendSV to request a context switch. */ \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ \ /* Barriers are normally not required but do ensure the code is completely \ * within the specified behaviour for the architecture. */ \ __dsb( portSY_FULL_READ_WRITE ); \ __isb( portSY_FULL_READ_WRITE ); \ } /*-----------------------------------------------------------*/ #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); #define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() #define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x ) /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /* Port specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #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. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) __clz( ( uxReadyPriorities ) ) ) #endif /* taskRECORD_READY_PRIORITY */ /*-----------------------------------------------------------*/ /* 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 * (which build with all the ports) will build. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* portNOP() is not required by this port. */ #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE __forceinline #endif /*-----------------------------------------------------------*/ static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI ) { __asm { /* Barrier instructions are not used as this function is only used to * lower the BASEPRI value. */ /* *INDENT-OFF* */ msr basepri, ulBASEPRI /* *INDENT-ON* */ } } /*-----------------------------------------------------------*/ static portFORCE_INLINE void vPortRaiseBASEPRI( void ) { uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY; __asm { /* Set BASEPRI to the max syscall priority to effect a critical * section. */ /* *INDENT-OFF* */ msr basepri, ulNewBASEPRI dsb isb /* *INDENT-ON* */ } } /*-----------------------------------------------------------*/ static portFORCE_INLINE void vPortClearBASEPRIFromISR( void ) { __asm { /* Set BASEPRI to 0 so no interrupts are masked. This function is only * used to lower the mask in an interrupt, so memory barriers are not * used. */ /* *INDENT-OFF* */ msr basepri, # 0 /* *INDENT-ON* */ } } /*-----------------------------------------------------------*/ static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void ) { uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY; __asm { /* Set BASEPRI to the max syscall priority to effect a critical * section. */ /* *INDENT-OFF* */ mrs ulReturn, basepri msr basepri, ulNewBASEPRI dsb isb /* *INDENT-ON* */ } return ulReturn; } /*-----------------------------------------------------------*/ static portFORCE_INLINE BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. */ __asm { /* *INDENT-OFF* */ mrs ulCurrentInterrupt, ipsr /* *INDENT-ON* */ } if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM_CM4F/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM4F port. *----------------------------------------------------------*/ /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #ifndef __TARGET_FPU_VFP #error This port can only be used when the project options are configured to enable hardware floating point support. #endif #if configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ #endif /* Legacy macro for backward compatibility only. This macro used to be used to * replace the function that configures the clock used to generate the tick * interrupt (prvSetupTimerInterrupt()), but now the function is declared weak so * the application writer can override it by simply defining a function of the * same name (vApplicationSetupTickInterrupt()). */ #ifndef configOVERRIDE_DEFAULT_TICK_CONFIGURATION #define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0 #endif /* Constants required to manipulate the core. Registers first... */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) /* ...then bits in the registers. */ #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) /* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7 * r0p1 port. */ #define portCPUID ( *( ( volatile uint32_t * ) 0xE000ed00 ) ) #define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) #define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) #define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) ) #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ #define portVECTACTIVE_MASK ( 0xFFUL ) /* Constants required to manipulate the VFP. */ #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_EXC_RETURN ( 0xfffffffd ) /* The systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /* A fiddle factor to estimate the number of SysTick counts that would have * occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) /* Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ); /* * Exception handlers. */ void xPortPendSVHandler( void ); void xPortSysTickHandler( void ); void vPortSVCHandler( void ); /* * Start first task is a separate function so it can be tested in isolation. */ static void prvStartFirstTask( void ); /* * Functions defined in portasm.s to enable the VFP. */ static void prvEnableVFP( void ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* Each task maintains its own interrupt status in the critical nesting * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* * The number of SysTick increments that make up one tick period. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulTimerCountsForOneTick = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * The maximum number of tick periods that can be suppressed is limited by the * 24 bit resolution of the SysTick timer. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t xMaximumPossibleSuppressedTicks = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Compensate for the CPU cycles that pass while the SysTick is stopped (low * power functionality only. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. */ #if ( configASSERT_DEFINED == 1 ) static uint8_t ucMaxSysCallPriority = 0; static uint32_t ulMaxPRIGROUPValue = 0; static const volatile uint8_t * const pcInterruptPriorityRegisters = ( uint8_t * ) portNVIC_IP_REGISTERS_OFFSET_16; #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ /* Offset added to account for the way the MCU uses the stack on entry/exit * of interrupts, and to ensure alignment. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */ /* Save code space by skipping register initialisation. */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ /* A save method is being used that requires each task to maintain its * own exec return value. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). * * Artificially force an assert() to be triggered if configASSERT() is * defined, then stop here so application writers can catch the error. */ configASSERT( uxCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); for( ; ; ) { } } /*-----------------------------------------------------------*/ __asm void vPortSVCHandler( void ) { /* *INDENT-OFF* */ PRESERVE8 /* Get the location of the current TCB. */ ldr r3, =pxCurrentTCB ldr r1, [ r3 ] ldr r0, [ r1 ] /* Pop the core registers. */ ldmia r0!, {r4-r11,r14} msr psp, r0 isb mov r0, #0 msr basepri, r0 bx r14 /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ __asm void prvStartFirstTask( void ) { /* *INDENT-OFF* */ PRESERVE8 /* Use the NVIC offset register to locate the stack. */ ldr r0, =0xE000ED08 ldr r0, [ r0 ] ldr r0, [ r0 ] /* Set the msp back to the start of the stack. */ msr msp, r0 /* Clear the bit that indicates the FPU is in use in case the FPU was used * before the scheduler was started - which would otherwise result in the * unnecessary leaving of space in the SVC stack for lazy saving of FPU * registers. */ mov r0, #0 msr control, r0 /* Globally enable interrupts. */ cpsie i cpsie f dsb isb /* Call SVC to start the first task. */ svc 0 nop nop /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ __asm void prvEnableVFP( void ) { /* *INDENT-OFF* */ PRESERVE8 /* The FPU enable bits are in the CPACR. */ ldr.w r0, =0xE000ED88 ldr r1, [ r0 ] /* Enable CP10 and CP11 coprocessors, then save back. */ orr r1, r1, #( 0xf << 20 ) str r1, [ r0 ] bx r14 nop /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); /* This port can be used on all revisions of the Cortex-M7 core other than * the r0p1 parts. r0p1 parts should use the port from the * /source/portable/GCC/ARM_CM7/r0p1 directory. */ configASSERT( portCPUID != portCORTEX_M7_r0p1_ID ); configASSERT( portCPUID != portCORTEX_M7_r0p0_ID ); #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API * functions can be called. ISR safe functions are those that end in * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* The kernel interrupt priority should be set to the lowest * priority. */ configASSERT( ucMaxPriorityValue == ( configKERNEL_INTERRUPT_PRIORITY & ucMaxPriorityValue ) ); /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { ulMaxPRIGROUPValue--; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); } #endif /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; /* Restore the clobbered interrupt priority register to its original * value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Ensure the VFP is enabled - it should be anyway. */ prvEnableVFP(); /* Lazy save always. */ *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; /* Start the first task. */ prvStartFirstTask(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); uxCriticalNesting++; /* 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 * 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 * assert function also uses a critical section. */ if( uxCriticalNesting == 1 ) { configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ __asm void xPortPendSVHandler( void ) { extern uxCriticalNesting; extern pxCurrentTCB; extern vTaskSwitchContext; /* *INDENT-OFF* */ PRESERVE8 mrs r0, psp isb /* Get the location of the current TCB. */ ldr r3, =pxCurrentTCB ldr r2, [ r3 ] /* Is the task using the FPU context? If so, push high vfp registers. */ tst r14, #0x10 it eq vstmdbeq r0!, {s16-s31} /* Save the core registers. */ stmdb r0!, {r4-r11, r14} /* Save the new top of stack into the first member of the TCB. */ str r0, [ r2 ] stmdb sp!, {r0, r3} mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY msr basepri, r0 dsb isb bl vTaskSwitchContext mov r0, #0 msr basepri, r0 ldmia sp!, {r0, r3} /* The first item in pxCurrentTCB is the task top of stack. */ ldr r1, [ r3 ] ldr r0, [ r1 ] /* Pop the core registers. */ ldmia r0!, {r4-r11, r14} /* Is the task using the FPU context? If so, pop the high vfp registers * too. */ tst r14, #0x10 it eq vldmiaeq r0!, {s16-s31} msr psp, r0 isb #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */ #if WORKAROUND_PMU_CM001 == 1 push { r14 } pop { pc } nop #endif #endif bx r14 /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { /* The SysTick runs at the lowest interrupt priority, so when this interrupt * executes all interrupts must be unmasked. There is therefore no need to * save and then restore the interrupt mask value as its value is already * known - therefore the slightly faster vPortRaiseBASEPRI() function is used * in place of portSET_INTERRUPT_MASK_FROM_ISR(). */ vPortRaiseBASEPRI(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* A context switch is required. Context switching is performed in * the PendSV interrupt. Pend the PendSV interrupt. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } vPortClearBASEPRIFromISR(); } /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __weak void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __disable_irq(); __dsb( portSY_FULL_READ_WRITE ); __isb( portSY_FULL_READ_WRITE ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the __disable_irq() * call above. */ __enable_irq(); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __dsb( portSY_FULL_READ_WRITE ); __wfi(); __isb( portSY_FULL_READ_WRITE ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the __disable_irq() call above. */ __enable_irq(); __dsb( portSY_FULL_READ_WRITE ); __isb( portSY_FULL_READ_WRITE ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __disable_irq(); __dsb( portSY_FULL_READ_WRITE ); __isb( portSY_FULL_READ_WRITE ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __enable_irq(); } } #endif /* #if configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ /* * Setup the SysTick timer to generate the tick interrupts at the required * frequency. */ #if ( configOVERRIDE_DEFAULT_TICK_CONFIGURATION == 0 ) __weak void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and clear the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); } #endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */ /*-----------------------------------------------------------*/ __asm uint32_t vPortGetIPSR( void ) { /* *INDENT-OFF* */ PRESERVE8 mrs r0, ipsr bx r14 /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; /* Obtain the number of the currently executing interrupt. */ ulCurrentInterrupt = vPortGetIPSR(); /* Is the interrupt number a user defined interrupt? */ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /* Look up the interrupt's priority. */ ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Interrupts that use the FreeRTOS API must not be left at their * default priority of zero as that is the highest possible priority, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * and therefore also guaranteed to be invalid. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } /* Priority grouping: The interrupt controller (NVIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined * to be pre-emption priority bits. The following assertion will fail if * this is not the case (if some bits represent a sub-priority). * * If the application only uses CMSIS libraries for interrupt * configuration then the correct setting can be achieved on all Cortex-M * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * scheduler. Note however that some vendor specific peripheral libraries * assume a non-zero priority group setting, in which cases using a value * of zero will result in unpredictable behaviour. */ configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); } #endif /* configASSERT_DEFINED */ ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM_CM4F/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /* Constants used with memory barrier intrinsics. */ #define portSY_FULL_READ_WRITE ( 15 ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ #define portYIELD() \ { \ /* Set a PendSV to request a context switch. */ \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ \ /* Barriers are normally not required but do ensure the code is completely \ * within the specified behaviour for the architecture. */ \ __dsb( portSY_FULL_READ_WRITE ); \ __isb( portSY_FULL_READ_WRITE ); \ } /*-----------------------------------------------------------*/ #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); #define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() #define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x ) /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /* Port specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #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. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) __clz( ( uxReadyPriorities ) ) ) #endif /* taskRECORD_READY_PRIORITY */ /*-----------------------------------------------------------*/ /* 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 * (which build with all the ports) will build. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* portNOP() is not required by this port. */ #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE __forceinline #endif /*-----------------------------------------------------------*/ static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI ) { __asm { /* Barrier instructions are not used as this function is only used to * lower the BASEPRI value. */ /* *INDENT-OFF* */ msr basepri, ulBASEPRI /* *INDENT-ON* */ } } /*-----------------------------------------------------------*/ static portFORCE_INLINE void vPortRaiseBASEPRI( void ) { uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY; __asm { /* Set BASEPRI to the max syscall priority to effect a critical * section. */ /* *INDENT-OFF* */ msr basepri, ulNewBASEPRI dsb isb /* *INDENT-ON* */ } } /*-----------------------------------------------------------*/ static portFORCE_INLINE void vPortClearBASEPRIFromISR( void ) { __asm { /* Set BASEPRI to 0 so no interrupts are masked. This function is only * used to lower the mask in an interrupt, so memory barriers are not * used. */ /* *INDENT-OFF* */ msr basepri, # 0 /* *INDENT-ON* */ } } /*-----------------------------------------------------------*/ static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void ) { uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY; __asm { /* Set BASEPRI to the max syscall priority to effect a critical * section. */ /* *INDENT-OFF* */ mrs ulReturn, basepri msr basepri, ulNewBASEPRI dsb isb /* *INDENT-ON* */ } return ulReturn; } /*-----------------------------------------------------------*/ static portFORCE_INLINE BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. */ __asm { /* *INDENT-OFF* */ mrs ulCurrentInterrupt, ipsr /* *INDENT-ON* */ } if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM_CM4_MPU/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM4 MPU port. *----------------------------------------------------------*/ /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #ifndef __TARGET_FPU_VFP #error This port can only be used when the project options are configured to enable hardware floating point support. #endif #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #ifndef configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS #warning "configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS is not defined. We recommend defining it to 0 in FreeRTOSConfig.h for better security." #define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1 #endif /* Constants required to access and manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SHPR2_REG ( *( ( volatile uint32_t * ) 0xe000ed1c ) ) #define portNVIC_SYS_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portNVIC_MEM_FAULT_ENABLE ( 1UL << 16UL ) /* Constants used to detect Cortex-M7 r0p0 and r0p1 cores, and ensure * that a work around is active for errata 837070. */ #define portCPUID ( *( ( volatile uint32_t * ) 0xE000ed00 ) ) #define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) #define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) /* Constants required to access and manipulate the MPU. */ #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_REGION_BASE_ADDRESS_REG ( *( ( volatile uint32_t * ) 0xe000ed9C ) ) #define portMPU_REGION_ATTRIBUTE_REG ( *( ( volatile uint32_t * ) 0xe000edA0 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) #define portMPU_ENABLE ( 0x01UL ) #define portMPU_BACKGROUND_ENABLE ( 1UL << 2UL ) #define portPRIVILEGED_EXECUTION_START_ADDRESS ( 0UL ) #define portMPU_REGION_VALID ( 0x10UL ) #define portMPU_REGION_ENABLE ( 0x01UL ) #define portPERIPHERALS_START_ADDRESS 0x40000000UL #define portPERIPHERALS_END_ADDRESS 0x5FFFFFFFUL /* Constants required to access and manipulate the SysTick. */ #define portNVIC_SYSTICK_CLK ( 0x00000004UL ) #define portNVIC_SYSTICK_INT ( 0x00000002UL ) #define portNVIC_SYSTICK_ENABLE ( 0x00000001UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) #define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /* Constants required to manipulate the VFP. */ #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34UL ) /* Floating point context control register. */ #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000UL ) #define portINITIAL_EXC_RETURN ( 0xfffffffdUL ) #define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 ) #define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) #define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) ) #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) /* Offsets in the stack to the parameters when inside the SVC handler. */ #define portOFFSET_TO_PC ( 6 ) /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) /* Each task maintains its own interrupt status in the critical nesting * variable. Note this is not saved as part of the task context as context * switches can only occur when uxCriticalNesting is zero. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* * Setup the timer to generate the tick interrupts. */ void vSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; /* * Configure a number of standard MPU regions that are used by all tasks. */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; /* * Start first task is a separate function so it can be tested in isolation. */ static void prvStartFirstTask( void ) PRIVILEGED_FUNCTION; /* * Return the smallest MPU region size that a given number of bytes will fit * into. The region size is returned as the value that should be programmed * into the region attribute register for that region. */ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) PRIVILEGED_FUNCTION; /* * Standard FreeRTOS exception handlers. */ void xPortPendSVHandler( void ) PRIVILEGED_FUNCTION; void xPortSysTickHandler( void ) PRIVILEGED_FUNCTION; void vPortSVCHandler( void ) PRIVILEGED_FUNCTION; /* * Starts the scheduler by restoring the context of the first task to run. */ static void prvRestoreContextOfFirstTask( void ) PRIVILEGED_FUNCTION; /* * C portion of the SVC handler. The SVC handler is split between an asm entry * and a C wrapper for simplicity of coding and maintenance. */ void prvSVCHandler( uint32_t * pulRegisters ) __attribute__( ( used ) ) PRIVILEGED_FUNCTION; /* * Function to enable the VFP. */ static void vPortEnableVFP( void ); /* * Utility function. */ static uint32_t prvPortGetIPSR( void ); /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. */ #if ( configASSERT_DEFINED == 1 ) static uint8_t ucMaxSysCallPriority = 0; static uint32_t ulMaxPRIGROUPValue = 0; static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const uint8_t * ) portNVIC_IP_REGISTERS_OFFSET_16; #endif /* configASSERT_DEFINED */ /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ BaseType_t xIsPrivileged( void ); /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit[0] = 0 --> The processor is running privileged * Bit[0] = 1 --> The processor is running unprivileged. */ void vResetPrivilege( void ); /** * @brief Enter critical section. */ #if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL; #else void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; #endif /** * @brief Exit from critical section. */ #if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL; #else void vPortExitCritical( void ) PRIVILEGED_FUNCTION; #endif /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ pxTopOfStack--; *pxTopOfStack = 0; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ /* A save method is being used that requires each task to maintain its * own exec return value. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack -= 9; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ if( xRunPrivileged == pdTRUE ) { *pxTopOfStack = portINITIAL_CONTROL_IF_PRIVILEGED; } else { *pxTopOfStack = portINITIAL_CONTROL_IF_UNPRIVILEGED; } return pxTopOfStack; } /*-----------------------------------------------------------*/ void prvSVCHandler( uint32_t * pulParam ) { uint8_t ucSVCNumber; uint32_t ulReg, ulPC; #if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) extern uint32_t __syscalls_flash_start__; extern uint32_t __syscalls_flash_end__; #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ /* The stack contains: r0, r1, r2, r3, r12, LR, PC and xPSR. The first * argument (r0) is pulParam[ 0 ]. */ ulPC = pulParam[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) { case portSVC_START_SCHEDULER: portNVIC_SHPR2_REG |= portNVIC_SVC_PRI; prvRestoreContextOfFirstTask(); break; case portSVC_YIELD: portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; /* Barriers are normally not required * but do ensure the code is completely * within the specified behaviour for the * architecture. */ __asm volatile ( "dsb" ); __asm volatile ( "isb" ); break; #if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the * svc was raised from any of the * system calls. */ if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) { __asm { /* *INDENT-OFF* */ mrs ulReg, control /* Obtain current control value. */ bic ulReg, # 1 /* Set privilege bit. */ msr control, ulReg /* Write back new control value. */ /* *INDENT-ON* */ } } break; #else /* if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ case portSVC_RAISE_PRIVILEGE: __asm { /* *INDENT-OFF* */ mrs ulReg, control /* Obtain current control value. */ bic ulReg, # 1 /* Set privilege bit. */ msr control, ulReg /* Write back new control value. */ /* *INDENT-ON* */ } break; #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ default: /* Unknown SVC call. */ break; } } /*-----------------------------------------------------------*/ __asm void vPortSVCHandler( void ) { extern prvSVCHandler /* *INDENT-OFF* */ PRESERVE8 /* Assumes psp was in use. */ #ifndef USE_PROCESS_STACK /* Code should not be required if a main() is using the process stack. */ tst lr, # 4 ite eq mrseq r0, msp mrsne r0, psp #else mrs r0, psp #endif b prvSVCHandler /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ __asm void prvRestoreContextOfFirstTask( void ) { /* *INDENT-OFF* */ PRESERVE8 ldr r0, =0xE000ED08 /* Use the NVIC offset register to locate the stack. */ ldr r0, [ r0 ] ldr r0, [ r0 ] msr msp, r0 /* Set the msp back to the start of the stack. */ ldr r3, =pxCurrentTCB /* Restore the context. */ ldr r1, [ r3 ] ldr r0, [ r1 ] /* The first item in the TCB is the task top of stack. */ add r1, r1, #4 /* Move onto the second item in the TCB... */ dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* MPU_CTRL register. */ ldr r3, [ r2 ] /* Read the value of MPU_CTRL. */ bic r3, r3, # 1 /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ str r3, [ r2 ] /* Disable MPU. */ ldr r2, =0xe000ed9c /* Region Base Address register. */ ldmia r1 !, { r4 - r11 } /* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */ stmia r2, { r4 - r11 } /* Write 4 sets of MPU registers [MPU Region # 4 - 7]. */ #if ( configTOTAL_MPU_REGIONS == 16 ) ldmia r1 !, { r4 - r11 } /* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */ stmia r2, { r4 - r11 } /* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */ ldmia r1 !, { r4 - r11 } /* Read 4 sets of MPU registers [MPU Region # 12 - 15]. */ stmia r2, { r4 - r11 } /* Write 4 sets of MPU registers. [MPU Region # 12 - 15]. */ #endif /* configTOTAL_MPU_REGIONS == 16. */ ldr r2, =0xe000ed94 /* MPU_CTRL register. */ ldr r3, [ r2 ] /* Read the value of MPU_CTRL. */ orr r3, r3, #1 /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ str r3, [ r2 ] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ ldmia r0 !, { r3 - r11, r14 } /* Pop the registers that are not automatically saved on exception entry. */ msr control, r3 msr psp, r0 /* Restore the task stack pointer. */ mov r0, #0 msr basepri, r0 bx r14 nop /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); /* Errata 837070 workaround must only be enabled on Cortex-M7 r0p0 * and r0p1 cores. */ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) configASSERT( ( portCPUID == portCORTEX_M7_r0p1_ID ) || ( portCPUID == portCORTEX_M7_r0p0_ID ) ); #else /* When using this port on a Cortex-M7 r0p0 or r0p1 core, define * configENABLE_ERRATA_837070_WORKAROUND to 1 in your * FreeRTOSConfig.h. */ configASSERT( portCPUID != portCORTEX_M7_r0p1_ID ); configASSERT( portCPUID != portCORTEX_M7_r0p0_ID ); #endif #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API * functions can be called. ISR safe functions are those that end in * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { ulMaxPRIGROUPValue--; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); } #endif /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; /* Restore the clobbered interrupt priority register to its original * value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* Make PendSV and SysTick the same priority as the kernel, and the SVC * handler higher priority so it can be used to exit a critical section (where * lower priorities are masked). */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Configure the regions in the MPU that are common to all tasks. */ prvSetupMPU(); /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Ensure the VFP is enabled - it should be anyway. */ vPortEnableVFP(); /* Lazy save always. */ *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; /* Start the first task. */ prvStartFirstTask(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ __asm void prvStartFirstTask( void ) { /* *INDENT-OFF* */ PRESERVE8 /* Use the NVIC offset register to locate the stack. */ ldr r0, =0xE000ED08 ldr r0, [ r0 ] ldr r0, [ r0 ] /* Set the msp back to the start of the stack. */ msr msp, r0 /* Clear the bit that indicates the FPU is in use in case the FPU was used * before the scheduler was started - which would otherwise result in the * unnecessary leaving of space in the SVC stack for lazy saving of FPU * registers. */ mov r0, #0 msr control, r0 /* Globally enable interrupts. */ cpsie i cpsie f dsb isb svc portSVC_START_SCHEDULER /* System call to start first task. */ nop nop /* *INDENT-ON* */ } void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { #if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); portDISABLE_INTERRUPTS(); uxCriticalNesting++; portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { portDISABLE_INTERRUPTS(); uxCriticalNesting++; } #else portDISABLE_INTERRUPTS(); uxCriticalNesting++; #endif } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { #if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } portMEMORY_BARRIER(); portRESET_PRIVILEGE(); portMEMORY_BARRIER(); } else { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } #else configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } #endif } /*-----------------------------------------------------------*/ __asm void xPortPendSVHandler( void ) { extern uxCriticalNesting; extern pxCurrentTCB; extern vTaskSwitchContext; /* *INDENT-OFF* */ PRESERVE8 mrs r0, psp ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */ ldr r2, [ r3 ] tst r14, #0x10 /* Is the task using the FPU context? If so, push high vfp registers. */ it eq vstmdbeq r0 !, { s16 - s31 } mrs r1, control stmdb r0 !, { r1, r4 - r11, r14 } /* Save the remaining registers. */ str r0, [ r2 ] /* Save the new top of stack into the first member of the TCB. */ stmdb sp !, { r0, r3 } mov r0, # configMAX_SYSCALL_INTERRUPT_PRIORITY #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) cpsid i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ #endif msr basepri, r0 dsb isb #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) cpsie i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ #endif bl vTaskSwitchContext mov r0, #0 msr basepri, r0 ldmia sp !, { r0, r3 } /* Restore the context. */ ldr r1, [ r3 ] ldr r0, [ r1 ] /* The first item in the TCB is the task top of stack. */ add r1, r1, #4 /* Move onto the second item in the TCB... */ dmb /* Complete outstanding transfers before disabling MPU. */ ldr r2, =0xe000ed94 /* MPU_CTRL register. */ ldr r3, [ r2 ] /* Read the value of MPU_CTRL. */ bic r3, r3, #1 /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ str r3, [ r2 ] /* Disable MPU. */ ldr r2, =0xe000ed9c /* Region Base Address register. */ ldmia r1 !, { r4 - r11 } /* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */ stmia r2, { r4 - r11 } /* Write 4 sets of MPU registers [MPU Region # 4 - 7]. */ #if ( configTOTAL_MPU_REGIONS == 16 ) ldmia r1 !, { r4 - r11 } /* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */ stmia r2, { r4 - r11 } /* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */ ldmia r1 !, { r4 - r11 } /* Read 4 sets of MPU registers [MPU Region # 12 - 15]. */ stmia r2, { r4 - r11 } /* Write 4 sets of MPU registers. [MPU Region # 12 - 15]. */ #endif /* configTOTAL_MPU_REGIONS == 16. */ ldr r2, =0xe000ed94 /* MPU_CTRL register. */ ldr r3, [ r2 ] /* Read the value of MPU_CTRL. */ orr r3, r3, #1 /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ str r3, [ r2 ] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ ldmia r0 !, { r3 - r11, r14 } /* Pop the registers that are not automatically saved on exception entry. */ msr control, r3 tst r14, #0x10 /* Is the task using the FPU context? If so, pop the high vfp registers too. */ it eq vldmiaeq r0 !, { s16 - s31 } msr psp, r0 bx r14 nop /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { uint32_t ulDummy; ulDummy = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* Pend a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy ); } /*-----------------------------------------------------------*/ /* * Setup the systick timer to generate the tick interrupts at the required * frequency. */ __weak void vSetupTimerInterrupt( void ) { /* Reset the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE; } /*-----------------------------------------------------------*/ __asm void vPortSwitchToUserMode( void ) { /* *INDENT-OFF* */ PRESERVE8 mrs r0, control orr r0, #1 msr control, r0 bx r14 /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ __asm void vPortEnableVFP( void ) { /* *INDENT-OFF* */ PRESERVE8 ldr.w r0, =0xE000ED88 /* The FPU enable bits are in the CPACR. */ ldr r1, [ r0 ] orr r1, r1, #( 0xf << 20 ) /* Enable CP10 and CP11 coprocessors, then save back. */ str r1, [ r0 ] bx r14 nop nop /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ static void prvSetupMPU( void ) { extern uint32_t __privileged_functions_start__; extern uint32_t __privileged_functions_end__; extern uint32_t __FLASH_segment_start__; extern uint32_t __FLASH_segment_end__; extern uint32_t __privileged_data_start__; extern uint32_t __privileged_data_end__; /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check the expected MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) { /* First setup the unprivileged flash for unprivileged read only access. */ portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __FLASH_segment_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | ( portUNPRIVILEGED_FLASH_REGION ); portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_READ_ONLY ) | ( ( configTEX_S_C_B_FLASH & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( prvGetMPURegionSizeSetting( ( uint32_t ) __FLASH_segment_end__ - ( uint32_t ) __FLASH_segment_start__ ) ) | ( portMPU_REGION_ENABLE ); /* Setup the privileged flash for privileged only access. This is where * the kernel code is placed. */ portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_functions_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | ( portPRIVILEGED_FLASH_REGION ); portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_PRIVILEGED_READ_ONLY ) | ( ( configTEX_S_C_B_FLASH & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_functions_end__ - ( uint32_t ) __privileged_functions_start__ ) ) | ( portMPU_REGION_ENABLE ); /* Setup the privileged data RAM region. This is where the kernel data * is placed. */ portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | ( portPRIVILEGED_RAM_REGION ); portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ) | ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_data_end__ - ( uint32_t ) __privileged_data_start__ ) | ( portMPU_REGION_ENABLE ); /* By default allow everything to access the general peripherals. The * system peripherals and registers are protected. */ portMPU_REGION_BASE_ADDRESS_REG = ( portPERIPHERALS_START_ADDRESS ) | ( portMPU_REGION_VALID ) | ( portGENERAL_PERIPHERALS_REGION ); portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_READ_WRITE | portMPU_REGION_EXECUTE_NEVER ) | ( prvGetMPURegionSizeSetting( portPERIPHERALS_END_ADDRESS - portPERIPHERALS_START_ADDRESS ) ) | ( portMPU_REGION_ENABLE ); /* Enable the memory fault exception. */ portNVIC_SYS_CTRL_STATE_REG |= portNVIC_MEM_FAULT_ENABLE; /* Enable the MPU with the background region configured. */ portMPU_CTRL_REG |= ( portMPU_ENABLE | portMPU_BACKGROUND_ENABLE ); } } /*-----------------------------------------------------------*/ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) { uint32_t ulRegionSize, ulReturnValue = 4; /* 32 is the smallest region size, 31 is the largest valid value for * ulReturnValue. */ for( ulRegionSize = 32UL; ulReturnValue < 31UL; ( ulRegionSize <<= 1UL ) ) { if( ulActualSizeInBytes <= ulRegionSize ) { break; } else { ulReturnValue++; } } /* Shift the code by one before returning so it can be written directly * into the the correct bit position of the attribute register. */ return( ulReturnValue << 1UL ); } /*-----------------------------------------------------------*/ __asm BaseType_t xIsPrivileged( void ) { /* *INDENT-OFF* */ PRESERVE8 mrs r0, control /* r0 = CONTROL. */ tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ ite ne movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ bx lr /* Return. */ /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ __asm void vResetPrivilege( void ) { /* *INDENT-OFF* */ PRESERVE8 mrs r0, control /* r0 = CONTROL. */ orrs r0, #1 /* r0 = r0 | 1. */ msr control, r0 /* CONTROL = r0. */ bx lr /* Return. */ /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth ) { extern uint32_t __SRAM_segment_start__; extern uint32_t __SRAM_segment_end__; extern uint32_t __privileged_data_start__; extern uint32_t __privileged_data_end__; int32_t lIndex; uint32_t ul; if( xRegions == NULL ) { /* No MPU regions are specified so allow access to all RAM. */ xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = ( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */ ( portMPU_REGION_VALID ) | ( portSTACK_REGION ); /* Region number. */ xMPUSettings->xRegion[ 0 ].ulRegionAttribute = ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ) | ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( prvGetMPURegionSizeSetting( ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__ ) ) | ( portMPU_REGION_ENABLE ); /* Invalidate user configurable regions. */ for( ul = 1UL; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) { xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID ); xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; } } else { /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that the * stack region has already been configured. */ if( ulStackDepth > 0 ) { /* Define the region that allows access to the stack. */ xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = ( ( uint32_t ) pxBottomOfStack ) | ( portMPU_REGION_VALID ) | ( portSTACK_REGION ); /* Region number. */ xMPUSettings->xRegion[ 0 ].ulRegionAttribute = ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ) | ( prvGetMPURegionSizeSetting( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) ) | ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( portMPU_REGION_ENABLE ); } lIndex = 0; for( ul = 1UL; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) { if( ( xRegions[ lIndex ] ).ulLengthInBytes > 0UL ) { /* Translate the generic region definition contained in * xRegions into the CM4 specific MPU settings that are then * stored in xMPUSettings. */ xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) | ( portMPU_REGION_VALID ) | ( ul - 1UL ); /* Region number. */ xMPUSettings->xRegion[ ul ].ulRegionAttribute = ( prvGetMPURegionSizeSetting( xRegions[ lIndex ].ulLengthInBytes ) ) | ( xRegions[ lIndex ].ulParameters ) | ( portMPU_REGION_ENABLE ); } else { /* Invalidate the region. */ xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID ); xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; } lIndex++; } } } /*-----------------------------------------------------------*/ __asm uint32_t prvPortGetIPSR( void ) { /* *INDENT-OFF* */ PRESERVE8 mrs r0, ipsr bx r14 /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; /* Obtain the number of the currently executing interrupt. */ ulCurrentInterrupt = prvPortGetIPSR(); /* Is the interrupt number a user defined interrupt? */ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /* Look up the interrupt's priority. */ ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Interrupts that use the FreeRTOS API must not be left at their * default priority of zero as that is the highest possible priority, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * and therefore also guaranteed to be invalid. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } /* Priority grouping: The interrupt controller (NVIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined * to be pre-emption priority bits. The following assertion will fail if * this is not the case (if some bits represent a sub-priority). * * If the application only uses CMSIS libraries for interrupt * configuration then the correct setting can be achieved on all Cortex-M * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * scheduler. Note however that some vendor specific peripheral libraries * assume a non-zero priority group setting, in which cases using a value * of zero will result in unpredictable behaviour. */ configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); } #endif /* configASSERT_DEFINED */ ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM_CM4_MPU/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* MPU specific constants. */ #define portUSING_MPU_WRAPPERS 1 #define portPRIVILEGE_BIT ( 0x80000000UL ) #define portMPU_REGION_READ_WRITE ( 0x03UL << 24UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 0x05UL << 24UL ) #define portMPU_REGION_READ_ONLY ( 0x06UL << 24UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0x01UL << 24UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ( 0x02UL << 24UL ) #define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL ) #define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL ) /* Location of the TEX,S,C,B bits in the MPU Region Attribute and Size * Register (RASR). */ #define portMPU_RASR_TEX_S_C_B_LOCATION ( 16UL ) #define portMPU_RASR_TEX_S_C_B_MASK ( 0x3FUL ) /* MPU settings that can be overriden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) #endif /* * The TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits define the * memory type, and where necessary the cacheable and shareable properties * of the memory region. * * The TEX, C, and B bits together indicate the memory type of the region, * and: * - For Normal memory, the cacheable properties of the region. * - For Device memory, whether the region is shareable. * * For Normal memory regions, the S bit indicates whether the region is * shareable. For Strongly-ordered and Device memory, the S bit is ignored. * * See the following two tables for setting TEX, S, C and B bits for * unprivileged flash, privileged flash and privileged RAM regions. * +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | TEX | C | B | Memory type | Description or Normal region cacheability | Shareable? | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 000 | 0 | 0 | Strongly-ordered | Strongly ordered | Shareable | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 000 | 0 | 1 | Device | Shared device | Shareable | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 000 | 1 | 0 | Normal | Outer and inner write-through; no write allocate | S bit | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 000 | 1 | 1 | Normal | Outer and inner write-back; no write allocate | S bit | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 001 | 0 | 0 | Normal | Outer and inner Non-cacheable | S bit | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 001 | 0 | 1 | Reserved | Reserved | Reserved | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 001 | 1 | 0 | IMPLEMENTATION DEFINED | IMPLEMENTATION DEFINED | IMPLEMENTATION DEFINED | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 001 | 1 | 1 | Normal | Outer and inner write-back; write and read allocate | S bit | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 010 | 0 | 0 | Device | Non-shared device | Not shareable | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 010 | 0 | 1 | Reserved | Reserved | Reserved | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 010 | 1 | X | Reserved | Reserved | Reserved | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 011 | X | X | Reserved | Reserved | Reserved | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | 1BB | A | A | Normal | Cached memory, with AA and BB indicating the inner and | Reserved | | | | | | outer cacheability rules that must be exported on the | | | | | | | bus. See the table below for the cacheability policy | | | | | | | encoding. memory, BB=Outer policy, AA=Inner policy. | | +-----+---+---+------------------------+--------------------------------------------------------+-------------------------+ | +-----------------------------------------+----------------------------------------+ | AA or BB subfield of {TEX,C,B} encoding | Cacheability policy | +-----------------------------------------+----------------------------------------+ | 00 | Non-cacheable | +-----------------------------------------+----------------------------------------+ | 01 | Write-back, write and read allocate | +-----------------------------------------+----------------------------------------+ | 10 | Write-through, no write allocate | +-----------------------------------------+----------------------------------------+ | 11 | Write-back, no write allocate | +-----------------------------------------+----------------------------------------+ */ /* TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits for Flash * region. */ #ifndef configTEX_S_C_B_FLASH /* Default to TEX=000, S=1, C=1, B=1 for backward compatibility. */ #define configTEX_S_C_B_FLASH ( 0x07UL ) #endif /* TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits for SRAM * region. */ #ifndef configTEX_S_C_B_SRAM /* Default to TEX=000, S=1, C=1, B=1 for backward compatibility. */ #define configTEX_S_C_B_SRAM ( 0x07UL ) #endif #define portGENERAL_PERIPHERALS_REGION ( configTOTAL_MPU_REGIONS - 5UL ) #define portSTACK_REGION ( configTOTAL_MPU_REGIONS - 4UL ) #define portUNPRIVILEGED_FLASH_REGION ( configTOTAL_MPU_REGIONS - 3UL ) #define portPRIVILEGED_FLASH_REGION ( configTOTAL_MPU_REGIONS - 2UL ) #define portPRIVILEGED_RAM_REGION ( configTOTAL_MPU_REGIONS - 1UL ) #define portFIRST_CONFIGURABLE_REGION ( 0UL ) #define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 6UL ) #define portNUM_CONFIGURABLE_REGIONS ( configTOTAL_MPU_REGIONS - 5UL ) #define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus 1 to create space for the stack region. */ void vPortSwitchToUserMode( void ); #define portSWITCH_TO_USER_MODE() vPortSwitchToUserMode() typedef struct MPU_REGION_REGISTERS { uint32_t ulRegionBaseAddress; uint32_t ulRegionAttribute; } xMPU_REGION_REGISTERS; typedef struct MPU_SETTINGS { xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ]; } xMPU_SETTINGS; /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /* Constants used with memory barrier intrinsics. */ #define portSY_FULL_READ_WRITE ( 15 ) /*-----------------------------------------------------------*/ /* SVC numbers for various services. */ #define portSVC_START_SCHEDULER 0 #define portSVC_YIELD 1 #define portSVC_RAISE_PRIVILEGE 2 /* Scheduler utilities. */ #define portYIELD() __asm{ SVC portSVC_YIELD } #define portYIELD_WITHIN_API() \ { \ /* Set a PendSV to request a context switch. */ \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ \ /* Barriers are normally not required but do ensure the code is completely \ * within the specified behaviour for the architecture. */ \ __dsb( portSY_FULL_READ_WRITE ); \ __isb( portSY_FULL_READ_WRITE ); \ } /*-----------------------------------------------------------*/ #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); #define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() #define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x ) /*-----------------------------------------------------------*/ /* Architecture specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #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. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) __clz( ( uxReadyPriorities ) ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /*-----------------------------------------------------------*/ /* 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 * (which build with all the ports) will build. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* portNOP() is not required by this port. */ #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE __forceinline #endif /*-----------------------------------------------------------*/ extern BaseType_t xIsPrivileged( void ); extern void vResetPrivilege( void ); /** * @brief Checks whether or not the processor is privileged. * * @return 1 if the processor is already privileged, 0 otherwise. */ #define portIS_PRIVILEGED() xIsPrivileged() /** * @brief Raise an SVC request to raise privilege. */ #define portRAISE_PRIVILEGE() __asm { svc portSVC_RAISE_PRIVILEGE } /** * @brief Lowers the privilege level by setting the bit 0 of the CONTROL * register. */ #define portRESET_PRIVILEGE() vResetPrivilege() /*-----------------------------------------------------------*/ static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI ) { __asm { /* Barrier instructions are not used as this function is only used to * lower the BASEPRI value. */ /* *INDENT-OFF* */ msr basepri, ulBASEPRI /* *INDENT-ON* */ } } /*-----------------------------------------------------------*/ static portFORCE_INLINE void vPortRaiseBASEPRI( void ) { uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY; __asm { /* Set BASEPRI to the max syscall priority to effect a critical * section. */ /* *INDENT-OFF* */ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) cpsid i #endif msr basepri, ulNewBASEPRI dsb isb #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) cpsie i #endif /* *INDENT-ON* */ } } /*-----------------------------------------------------------*/ static portFORCE_INLINE void vPortClearBASEPRIFromISR( void ) { __asm { /* Set BASEPRI to 0 so no interrupts are masked. This function is only * used to lower the mask in an interrupt, so memory barriers are not * used. */ /* *INDENT-OFF* */ msr basepri, # 0 /* *INDENT-ON* */ } } /*-----------------------------------------------------------*/ static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void ) { uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY; __asm { /* Set BASEPRI to the max syscall priority to effect a critical * section. */ /* *INDENT-OFF* */ mrs ulReturn, basepri #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) cpsid i #endif msr basepri, ulNewBASEPRI dsb isb #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) cpsie i #endif /* *INDENT-ON* */ } return ulReturn; } /*-----------------------------------------------------------*/ static portFORCE_INLINE BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. */ __asm { mrs ulCurrentInterrupt, ipsr } if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /*-----------------------------------------------------------*/ #ifndef configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY #warning "configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY is not defined. We recommend defining it to 1 in FreeRTOSConfig.h for better security. https://www.FreeRTOS.org/FreeRTOS-V10.3.x.html" #define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 0 #endif /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM_CM7/ReadMe.txt ================================================ There are two options for running FreeRTOS on ARM Cortex-M7 microcontrollers. The best option depends on the revision of the ARM Cortex-M7 core in use. The revision is specified by an 'r' number, and a 'p' number, so will look something like 'r0p1'. Check the documentation for the microcontroller in use to find the revision of the Cortex-M7 core used in that microcontroller. If in doubt, use the FreeRTOS port provided specifically for r0p1 revisions, as that can be used with all core revisions. The first option is to use the ARM Cortex-M4F port, and the second option is to use the Cortex-M7 r0p1 port - the latter containing a minor errata workaround. If the revision of the ARM Cortex-M7 core is not r0p1 then either option can be used, but it is recommended to use the FreeRTOS ARM Cortex-M4F port located in the /FreeRTOS/Source/portable/RVDS/ARM_CM4F directory. If the revision of the ARM Cortex-M7 core is r0p1 then use the FreeRTOS ARM Cortex-M7 r0p1 port located in the /FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1 directory. ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM_CM7/r0p1/port.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM7 port. *----------------------------------------------------------*/ /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #ifndef __TARGET_FPU_VFP #error This port can only be used when the project options are configured to enable hardware floating point support. #endif #if configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ #endif /* The __weak attribute does not work as you might expect with the Keil tools * so the configOVERRIDE_DEFAULT_TICK_CONFIGURATION constant must be set to 1 if * the application writer wants to provide their own implementation of * vPortSetupTimerInterrupt(). Ensure configOVERRIDE_DEFAULT_TICK_CONFIGURATION * is defined. */ #ifndef configOVERRIDE_DEFAULT_TICK_CONFIGURATION #define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0 #endif /* Constants required to manipulate the core. Registers first... */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) /* ...then bits in the registers. */ #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) #define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) ) #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ #define portVECTACTIVE_MASK ( 0xFFUL ) /* Constants required to manipulate the VFP. */ #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_EXC_RETURN ( 0xfffffffd ) /* The systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) /* A fiddle factor to estimate the number of SysTick counts that would have * occurred while the SysTick counter is stopped during tickless idle * calculations. */ #define portMISSED_COUNTS_FACTOR ( 94UL ) /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) /* Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the * configuration register. */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) #else /* Select the option to clock SysTick not at the same frequency as the core. */ #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif /* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ); /* * Exception handlers. */ void xPortPendSVHandler( void ); void xPortSysTickHandler( void ); void vPortSVCHandler( void ); /* * Start first task is a separate function so it can be tested in isolation. */ static void prvStartFirstTask( void ); /* * Functions defined in portasm.s to enable the VFP. */ static void prvEnableVFP( void ); /* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* Each task maintains its own interrupt status in the critical nesting * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* * The number of SysTick increments that make up one tick period. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulTimerCountsForOneTick = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * The maximum number of tick periods that can be suppressed is limited by the * 24 bit resolution of the SysTick timer. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t xMaximumPossibleSuppressedTicks = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Compensate for the CPU cycles that pass while the SysTick is stopped (low * power functionality only. */ #if ( configUSE_TICKLESS_IDLE == 1 ) static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. */ #if ( configASSERT_DEFINED == 1 ) static uint8_t ucMaxSysCallPriority = 0; static uint32_t ulMaxPRIGROUPValue = 0; static const volatile uint8_t * const pcInterruptPriorityRegisters = ( uint8_t * ) portNVIC_IP_REGISTERS_OFFSET_16; #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ /* * See header file for description. */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ /* Offset added to account for the way the MCU uses the stack on entry/exit * of interrupts, and to ensure alignment. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */ /* Save code space by skipping register initialisation. */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ /* A save method is being used that requires each task to maintain its * own exec return value. */ pxTopOfStack--; *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to * its caller as there is nothing to return to. If a task wants to exit it * should instead call vTaskDelete( NULL ). * * Artificially force an assert() to be triggered if configASSERT() is * defined, then stop here so application writers can catch the error. */ configASSERT( uxCriticalNesting == ~0UL ); portDISABLE_INTERRUPTS(); for( ; ; ) { } } /*-----------------------------------------------------------*/ __asm void vPortSVCHandler( void ) { /* *INDENT-OFF* */ PRESERVE8 /* Get the location of the current TCB. */ ldr r3, =pxCurrentTCB ldr r1, [ r3 ] ldr r0, [ r1 ] /* Pop the core registers. */ ldmia r0!, { r4-r11, r14 } msr psp, r0 isb mov r0, #0 msr basepri, r0 bx r14 /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ __asm void prvStartFirstTask( void ) { /* *INDENT-OFF* */ PRESERVE8 /* Use the NVIC offset register to locate the stack. */ ldr r0, =0xE000ED08 ldr r0, [ r0 ] ldr r0, [ r0 ] /* Set the msp back to the start of the stack. */ msr msp, r0 /* Clear the bit that indicates the FPU is in use in case the FPU was used * before the scheduler was started - which would otherwise result in the * unnecessary leaving of space in the SVC stack for lazy saving of FPU * registers. */ mov r0, #0 msr control, r0 /* Globally enable interrupts. */ cpsie i cpsie f dsb isb /* Call SVC to start the first task. */ svc 0 nop nop /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ __asm void prvEnableVFP( void ) { /* *INDENT-OFF* */ PRESERVE8 /* The FPU enable bits are in the CPACR. */ ldr.w r0, =0xE000ED88 ldr r1, [ r0 ] /* Enable CP10 and CP11 coprocessors, then save back. */ orr r1, r1, #( 0xf << 20 ) str r1, [ r0 ] bx r14 nop /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ /* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { #if ( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API * functions can be called. ISR safe functions are those that end in * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * * Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all * possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* The kernel interrupt priority should be set to the lowest * priority. */ configASSERT( ucMaxPriorityValue == ( configKERNEL_INTERRUPT_PRIORITY & ucMaxPriorityValue ) ); /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { ulMaxPRIGROUPValue--; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } #ifdef __NVIC_PRIO_BITS { /* Check the CMSIS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); } #endif #ifdef configPRIO_BITS { /* Check the FreeRTOS configuration that defines the number of * priority bits matches the number of priority bits actually queried * from the hardware. */ configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); } #endif /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; /* Restore the clobbered interrupt priority register to its original * value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* configASSERT_DEFINED */ /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; /* Start the timer that generates the tick ISR. Interrupts are disabled * here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Ensure the VFP is enabled - it should be anyway. */ prvEnableVFP(); /* Lazy save always. */ *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; /* Start the first task. */ prvStartFirstTask(); /* Should not get here! */ return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ configASSERT( uxCriticalNesting == 1000UL ); } /*-----------------------------------------------------------*/ void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); uxCriticalNesting++; /* 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 * 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 * assert function also uses a critical section. */ if( uxCriticalNesting == 1 ) { configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); } } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /*-----------------------------------------------------------*/ __asm void xPortPendSVHandler( void ) { extern uxCriticalNesting; extern pxCurrentTCB; extern vTaskSwitchContext; /* *INDENT-OFF* */ PRESERVE8 mrs r0, psp isb /* Get the location of the current TCB. */ ldr r3, =pxCurrentTCB ldr r2, [ r3 ] /* Is the task using the FPU context? If so, push high vfp registers. */ tst r14, #0x10 it eq vstmdbeq r0!, {s16-s31} /* Save the core registers. */ stmdb r0!, {r4-r11, r14 } /* Save the new top of stack into the first member of the TCB. */ str r0, [ r2 ] stmdb sp!, { r0, r3 } mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY cpsid i msr basepri, r0 dsb isb cpsie i bl vTaskSwitchContext mov r0, #0 msr basepri, r0 ldmia sp!, { r0, r3 } /* The first item in pxCurrentTCB is the task top of stack. */ ldr r1, [ r3 ] ldr r0, [ r1 ] /* Pop the core registers. */ ldmia r0!, { r4-r11, r14 } /* Is the task using the FPU context? If so, pop the high vfp registers * too. */ tst r14, #0x10 it eq vldmiaeq r0!, { s16-s31 } msr psp, r0 isb #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */ #if WORKAROUND_PMU_CM001 == 1 push { r14 } pop { pc } nop #endif #endif bx r14 /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ void xPortSysTickHandler( void ) { /* The SysTick runs at the lowest interrupt priority, so when this interrupt * executes all interrupts must be unmasked. There is therefore no need to * save and then restore the interrupt mask value as its value is already * known - therefore the slightly faster vPortRaiseBASEPRI() function is used * in place of portSET_INTERRUPT_MASK_FROM_ISR(). */ vPortRaiseBASEPRI(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* A context switch is required. Context switching is performed in * the PendSV interrupt. Pend the PendSV interrupt. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } vPortClearBASEPRIFromISR(); } /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) __weak void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ __disable_irq(); __dsb( portSY_FULL_READ_WRITE ); __isb( portSY_FULL_READ_WRITE ); /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Re-enable interrupts - see comments above the __disable_irq() * call above. */ __enable_irq(); } else { /* Stop the SysTick momentarily. The time the SysTick is stopped for * is accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Use the SysTick current-value register to determine the number of * SysTick decrements remaining until the next tick interrupt. If the * current-value register is zero, then there are actually * ulTimerCountsForOneTick decrements remaining, not zero, because the * SysTick requests the interrupt when decrementing from 1 to 0. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulTimerCountsForOneTick; } /* Calculate the reload value required to wait xExpectedIdleTime * tick periods. -1 is used because this code normally executes part * way through the first tick period. But if the SysTick IRQ is now * pending, then clear the IRQ, suppressing the first tick, and correct * the reload value to reflect that the second tick period is already * underway. The expected idle time is always at least two ticks. */ ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) { portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; ulReloadValue -= ulTimerCountsForOneTick; } if( ulReloadValue > ulStoppedTimerCompensation ) { ulReloadValue -= ulStoppedTimerCompensation; } /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to * zero. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can * set its parameter to 0 to indicate that its implementation contains * its own wait for interrupt or wait for event instruction, and so wfi * should not be executed again. However, the original expected idle * time variable must remain unmodified, so a copy is taken. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); if( xModifiableIdleTime > 0 ) { __dsb( portSY_FULL_READ_WRITE ); __wfi(); __isb( portSY_FULL_READ_WRITE ); } configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); /* Re-enable interrupts to allow the interrupt that brought the MCU * out of sleep mode to execute immediately. See comments above * the __disable_irq() call above. */ __enable_irq(); __dsb( portSY_FULL_READ_WRITE ); __isb( portSY_FULL_READ_WRITE ); /* Disable interrupts again because the clock is about to be stopped * and interrupts that execute while the clock is stopped will increase * any slippage between the time maintained by the RTOS and calendar * time. */ __disable_irq(); __dsb( portSY_FULL_READ_WRITE ); __isb( portSY_FULL_READ_WRITE ); /* Disable the SysTick clock without reading the * portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * the time the SysTick is stopped for is accounted for as best it can * be, but using the tickless mode will inevitably result in some tiny * drift of the time maintained by the kernel with respect to calendar * time*/ portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); /* Determine whether the SysTick has already counted to zero. */ if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { uint32_t ulCalculatedLoadValue; /* The tick interrupt ended the sleep (or is now pending), and * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG * with whatever remains of the new tick period. */ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); /* Don't allow a tiny value, or values that have somehow * underflowed because the post sleep hook did something * that took too long or because the SysTick current-value register * is zero. */ if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) { ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); } portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; /* As the pending tick will be processed as soon as this * function exits, the tick value maintained by the tick is stepped * forward by one less than the time spent waiting. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; } else { /* Something other than the tick interrupt ended the sleep. */ /* Use the SysTick current-value register to determine the * number of SysTick decrements remaining until the expected idle * time would have ended. */ ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) { /* If the SysTick is not using the core clock, the current- * value register might still be zero here. In that case, the * SysTick didn't load from the reload register, and there are * ulReloadValue decrements remaining in the expected idle * time, not zero. */ if( ulSysTickDecrementsLeft == 0 ) { ulSysTickDecrementsLeft = ulReloadValue; } } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Work out how long the sleep lasted rounded to complete tick * periods (not the ulReload value which accounted for part * ticks). */ ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; /* How many complete tick periods passed while the processor * was waiting? */ ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; /* The reload value is set to whatever fraction of a single tick * period remains. */ portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; } /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If * the SysTick is not using the core clock, temporarily configure it to * use the core clock. This configuration forces the SysTick to load * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready * to receive the standard value immediately. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) { portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; } #else { /* The temporary usage of the core clock has served its purpose, * as described above. Resume usage of the other clock. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The partial tick period already ended. Be sure the SysTick * counts it only once. */ portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; } portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ /* Step the tick to account for any tick periods that elapsed. */ vTaskStepTick( ulCompleteTickPeriods ); /* Exit with interrupts enabled. */ __enable_irq(); } } #endif /* #if configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ /* * Setup the SysTick timer to generate the tick interrupts at the required * frequency. */ #if ( configOVERRIDE_DEFAULT_TICK_CONFIGURATION == 0 ) __weak void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ #if ( configUSE_TICKLESS_IDLE == 1 ) { ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); } #endif /* configUSE_TICKLESS_IDLE */ /* Stop and clear the SysTick. */ portNVIC_SYSTICK_CTRL_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /* Configure SysTick to interrupt at the requested rate. */ portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); } #endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */ /*-----------------------------------------------------------*/ __asm uint32_t vPortGetIPSR( void ) { /* *INDENT-OFF* */ PRESERVE8 mrs r0, ipsr bx r14 /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) { uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; /* Obtain the number of the currently executing interrupt. */ ulCurrentInterrupt = vPortGetIPSR(); /* Is the interrupt number a user defined interrupt? */ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /* Look up the interrupt's priority. */ ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; /* The following assertion will fail if a service routine (ISR) for * an interrupt that has been assigned a priority above * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * function. ISR safe FreeRTOS API functions must *only* be called * from interrupts that have been assigned a priority at or below * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Numerically low interrupt priority numbers represent logically high * interrupt priorities, therefore the priority of the interrupt must * be set to a value equal to or numerically *higher* than * configMAX_SYSCALL_INTERRUPT_PRIORITY. * * Interrupts that use the FreeRTOS API must not be left at their * default priority of zero as that is the highest possible priority, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * and therefore also guaranteed to be invalid. * * FreeRTOS maintains separate thread and ISR API functions to ensure * interrupt entry is as fast and simple as possible. * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } /* Priority grouping: The interrupt controller (NVIC) allows the bits * that define each interrupt's priority to be split between bits that * define the interrupt's pre-emption priority bits and bits that define * the interrupt's sub-priority. For simplicity all bits must be defined * to be pre-emption priority bits. The following assertion will fail if * this is not the case (if some bits represent a sub-priority). * * If the application only uses CMSIS libraries for interrupt * configuration then the correct setting can be achieved on all Cortex-M * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * scheduler. Note however that some vendor specific peripheral libraries * assume a non-zero priority group setting, in which cases using a value * of zero will result in unpredictable behaviour. */ configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); } #endif /* configASSERT_DEFINED */ ================================================ FILE: FreeRTOS-comparison/portable/RVDS/ARM_CM7/r0p1/portmacro.h ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #ifndef PORTMACRO_H #define PORTMACRO_H /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ /*----------------------------------------------------------- * Port specific definitions. * * The settings in this file configure FreeRTOS correctly for the * given hardware and compiler. * * These settings should not be altered. *----------------------------------------------------------- */ /* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long typedef portSTACK_TYPE StackType_t; typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #else typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif /*-----------------------------------------------------------*/ /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 /* Constants used with memory barrier intrinsics. */ #define portSY_FULL_READ_WRITE ( 15 ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ #define portYIELD() \ { \ /* Set a PendSV to request a context switch. */ \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ \ /* Barriers are normally not required but do ensure the code is completely \ * within the specified behaviour for the architecture. */ \ __dsb( portSY_FULL_READ_WRITE ); \ __isb( portSY_FULL_READ_WRITE ); \ } /*-----------------------------------------------------------*/ #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ /* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); #define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() #define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 ) #define portENTER_CRITICAL() vPortEnterCritical() #define portEXIT_CRITICAL() vPortExitCritical() #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x ) /*-----------------------------------------------------------*/ /* Tickless idle/low power functionality. */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ /* Port specific optimisations. */ #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #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. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_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 ) __clz( ( uxReadyPriorities ) ) ) #endif /* taskRECORD_READY_PRIORITY */ /*-----------------------------------------------------------*/ /* 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 * (which build with all the ports) will build. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ #ifdef configASSERT void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* portNOP() is not required by this port. */ #define portNOP() #define portINLINE __inline #ifndef portFORCE_INLINE #define portFORCE_INLINE __forceinline #endif /*-----------------------------------------------------------*/ static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI ) { __asm { /* Barrier instructions are not used as this function is only used to * lower the BASEPRI value. */ /* *INDENT-OFF* */ msr basepri, ulBASEPRI /* *INDENT-ON* */ } } /*-----------------------------------------------------------*/ static portFORCE_INLINE void vPortRaiseBASEPRI( void ) { uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY; __asm { /* Set BASEPRI to the max syscall priority to effect a critical * section. */ /* *INDENT-OFF* */ cpsid i msr basepri, ulNewBASEPRI dsb isb cpsie i /* *INDENT-ON* */ } } /*-----------------------------------------------------------*/ static portFORCE_INLINE void vPortClearBASEPRIFromISR( void ) { __asm { /* Set BASEPRI to 0 so no interrupts are masked. This function is only * used to lower the mask in an interrupt, so memory barriers are not * used. */ /* *INDENT-OFF* */ msr basepri, # 0 /* *INDENT-ON* */ } } /*-----------------------------------------------------------*/ static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void ) { uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY; __asm { /* Set BASEPRI to the max syscall priority to effect a critical * section. */ /* *INDENT-OFF* */ mrs ulReturn, basepri cpsid i msr basepri, ulNewBASEPRI dsb isb cpsie i /* *INDENT-ON* */ } return ulReturn; } /*-----------------------------------------------------------*/ static portFORCE_INLINE BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. */ __asm { /* *INDENT-OFF* */ mrs ulCurrentInterrupt, ipsr /* *INDENT-ON* */ } if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; } /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* PORTMACRO_H */ ================================================ FILE: FreeRTOS-comparison/portable/readme.txt ================================================ Each real time kernel port consists of three files that contain the core kernel components and are common to every port, and one or more files that are specific to a particular microcontroller and/or compiler. + The FreeRTOS/Source/Portable/MemMang directory contains the five sample memory allocators as described on the https://www.FreeRTOS.org WEB site. + The other directories each contain files specific to a particular microcontroller or compiler, where the directory name denotes the compiler specific files the directory contains. For example, if you are interested in the [compiler] port for the [architecture] microcontroller, then the port specific files are contained in FreeRTOS/Source/Portable/[compiler]/[architecture] directory. If this is the only port you are interested in then all the other directories can be ignored. ================================================ FILE: FreeRTOS-comparison/queue.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ #include #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #include "FreeRTOS.h" #include "task.h" #include "queue.h" #if ( configUSE_CO_ROUTINES == 1 ) #include "croutine.h" #endif /* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified * because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined * for the header files above, but not in this file, in order to generate the * correct privileged Vs unprivileged linkage and placement. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ /* Constants used with the cRxLock and cTxLock structure members. */ #define queueUNLOCKED ( ( int8_t ) -1 ) #define queueLOCKED_UNMODIFIED ( ( int8_t ) 0 ) #define queueINT8_MAX ( ( int8_t ) 127 ) /* When the Queue_t structure is used to represent a base queue its pcHead and * pcTail members are used as pointers into the queue storage area. When the * Queue_t structure is used to represent a mutex pcHead and pcTail pointers are * not necessary, and the pcHead pointer is set to NULL to indicate that the * structure instead holds a pointer to the mutex holder (if any). Map alternative * names to the pcHead and structure member to ensure the readability of the code * is maintained. The QueuePointers_t and SemaphoreData_t types are used to form * a union as their usage is mutually exclusive dependent on what the queue is * being used for. */ #define uxQueueType pcHead #define queueQUEUE_IS_MUTEX NULL typedef struct QueuePointers { int8_t * pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */ int8_t * pcReadFrom; /*< Points to the last place that a queued item was read from when the structure is used as a queue. */ } QueuePointers_t; typedef struct SemaphoreData { TaskHandle_t xMutexHolder; /*< The handle of the task that holds the mutex. */ UBaseType_t uxRecursiveCallCount; /*< Maintains a count of the number of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */ } SemaphoreData_t; /* Semaphores do not actually store or copy data, so have an item size of * zero. */ #define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( UBaseType_t ) 0 ) #define queueMUTEX_GIVE_BLOCK_TIME ( ( TickType_t ) 0U ) #if ( configUSE_PREEMPTION == 0 ) /* If the cooperative scheduler is being used then a yield should not be * performed just because a higher priority task has been woken. */ #define queueYIELD_IF_USING_PREEMPTION() #else #define queueYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() #endif /* * Definition of the queue used by the scheduler. * Items are queued by copy, not reference. See the following link for the * rationale: https://www.FreeRTOS.org/Embedded-RTOS-Queues.html */ typedef struct QueueDefinition /* The old naming convention is used to prevent breaking kernel aware debuggers. */ { int8_t * pcHead; /*< Points to the beginning of the queue storage area. */ int8_t * pcWriteTo; /*< Points to the free next place in the storage area. */ union { QueuePointers_t xQueue; /*< Data required exclusively when this structure is used as a queue. */ SemaphoreData_t xSemaphore; /*< Data required exclusively when this structure is used as a semaphore. */ } u; List_t xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */ List_t xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */ volatile UBaseType_t uxMessagesWaiting; /*< The number of items currently in the queue. */ UBaseType_t uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */ UBaseType_t uxItemSize; /*< The size of each items that the queue will hold. */ volatile int8_t cRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ volatile int8_t cTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the memory used by the queue was statically allocated to ensure no attempt is made to free the memory. */ #endif #if ( configUSE_QUEUE_SETS == 1 ) struct QueueDefinition * pxQueueSetContainer; #endif #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxQueueNumber; uint8_t ucQueueType; #endif } xQUEUE; /* The old xQUEUE name is maintained above then typedefed to the new Queue_t * name below to enable the use of older kernel aware debuggers. */ typedef xQUEUE Queue_t; /*-----------------------------------------------------------*/ /* * The queue registry is just a means for kernel aware debuggers to locate * queue structures. It has no other purpose so is an optional component. */ #if ( configQUEUE_REGISTRY_SIZE > 0 ) /* The type stored within the queue registry array. This allows a name * to be assigned to each queue making kernel aware debugging a little * more user friendly. */ typedef struct QUEUE_REGISTRY_ITEM { const char * pcQueueName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ QueueHandle_t xHandle; } xQueueRegistryItem; /* The old xQueueRegistryItem name is maintained above then typedefed to the * new xQueueRegistryItem name below to enable the use of older kernel aware * debuggers. */ typedef xQueueRegistryItem QueueRegistryItem_t; /* The queue registry is simply an array of QueueRegistryItem_t structures. * The pcQueueName member of a structure being NULL is indicative of the * array position being vacant. */ PRIVILEGED_DATA QueueRegistryItem_t xQueueRegistry[ configQUEUE_REGISTRY_SIZE ]; #endif /* configQUEUE_REGISTRY_SIZE */ /* * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not * prevent an ISR from adding or removing items to the queue, but does prevent * an ISR from removing tasks from the queue event lists. If an ISR finds a * queue is locked it will instead increment the appropriate queue lock count * to indicate that a task may require unblocking. When the queue in unlocked * these lock counts are inspected, and the appropriate action taken. */ static void prvUnlockQueue( Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; /* * Uses a critical section to determine if there is any data in a queue. * * @return pdTRUE if the queue contains no items, otherwise pdFALSE. */ static BaseType_t prvIsQueueEmpty( const Queue_t * pxQueue ) PRIVILEGED_FUNCTION; /* * Uses a critical section to determine if there is any space in a queue. * * @return pdTRUE if there is no space, otherwise pdFALSE; */ static BaseType_t prvIsQueueFull( const Queue_t * pxQueue ) PRIVILEGED_FUNCTION; /* * Copies an item into the queue, either at the front of the queue or the * back of the queue. */ static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void * pvItemToQueue, const BaseType_t xPosition ) PRIVILEGED_FUNCTION; /* * Copies an item out of a queue. */ static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION; #if ( configUSE_QUEUE_SETS == 1 ) /* * Checks to see if a queue is a member of a queue set, and if so, notifies * the queue set that the queue contains data. */ static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; #endif /* * Called after a Queue_t structure has been allocated either statically or * dynamically to fill in the structure's members. */ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t * pucQueueStorage, const uint8_t ucQueueType, Queue_t * pxNewQueue ) PRIVILEGED_FUNCTION; /* * Mutexes are a special type of queue. When a mutex is created, first the * queue is created, then prvInitialiseMutex() is called to configure the queue * as a mutex. */ #if ( configUSE_MUTEXES == 1 ) static void prvInitialiseMutex( Queue_t * pxNewQueue ) PRIVILEGED_FUNCTION; #endif #if ( configUSE_MUTEXES == 1 ) /* * If a task waiting for a mutex causes the mutex holder to inherit a * priority, but the waiting task times out, then the holder should * disinherit the priority - but only down to the highest priority of any * other tasks that are waiting for the same mutex. This function returns * that priority. */ static UBaseType_t prvGetDisinheritPriorityAfterTimeout( const Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; #endif /*-----------------------------------------------------------*/ /* * Macro to mark a queue as locked. Locking a queue prevents an ISR from * accessing the queue event lists. */ #define prvLockQueue( pxQueue ) \ taskENTER_CRITICAL(); \ { \ if( ( pxQueue )->cRxLock == queueUNLOCKED ) \ { \ ( pxQueue )->cRxLock = queueLOCKED_UNMODIFIED; \ } \ if( ( pxQueue )->cTxLock == queueUNLOCKED ) \ { \ ( pxQueue )->cTxLock = queueLOCKED_UNMODIFIED; \ } \ } \ taskEXIT_CRITICAL() /* * Macro to increment cTxLock member of the queue data structure. It is * capped at the number of tasks in the system as we cannot unblock more * tasks than the number of tasks in the system. */ #define prvIncrementQueueTxLock( pxQueue, cTxLock ) \ { \ const UBaseType_t uxNumberOfTasks = uxTaskGetNumberOfTasks(); \ if( ( UBaseType_t ) ( cTxLock ) < uxNumberOfTasks ) \ { \ configASSERT( ( cTxLock ) != queueINT8_MAX ); \ ( pxQueue )->cTxLock = ( int8_t ) ( ( cTxLock ) + ( int8_t ) 1 ); \ } \ } /* * Macro to increment cRxLock member of the queue data structure. It is * capped at the number of tasks in the system as we cannot unblock more * tasks than the number of tasks in the system. */ #define prvIncrementQueueRxLock( pxQueue, cRxLock ) \ { \ const UBaseType_t uxNumberOfTasks = uxTaskGetNumberOfTasks(); \ if( ( UBaseType_t ) ( cRxLock ) < uxNumberOfTasks ) \ { \ configASSERT( ( cRxLock ) != queueINT8_MAX ); \ ( pxQueue )->cRxLock = ( int8_t ) ( ( cRxLock ) + ( int8_t ) 1 ); \ } \ } /*-----------------------------------------------------------*/ BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) { BaseType_t xReturn = pdPASS; Queue_t * const pxQueue = xQueue; configASSERT( pxQueue ); if( ( pxQueue != NULL ) && ( pxQueue->uxLength >= 1U ) && /* Check for multiplication overflow. */ ( ( SIZE_MAX / pxQueue->uxLength ) >= pxQueue->uxItemSize ) ) { taskENTER_CRITICAL(); { pxQueue->u.xQueue.pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */ pxQueue->uxMessagesWaiting = ( UBaseType_t ) 0U; pxQueue->pcWriteTo = pxQueue->pcHead; pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - 1U ) * pxQueue->uxItemSize ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */ pxQueue->cRxLock = queueUNLOCKED; pxQueue->cTxLock = queueUNLOCKED; if( xNewQueue == pdFALSE ) { /* If there are tasks blocked waiting to read from the queue, then * the tasks will remain blocked as after this function exits the queue * will still be empty. If there are tasks blocked waiting to write to * the queue, then one should be unblocked as after this function exits * it will be possible to write to it. */ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) { queueYIELD_IF_USING_PREEMPTION(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { /* Ensure the event queues start in the correct state. */ vListInitialise( &( pxQueue->xTasksWaitingToSend ) ); vListInitialise( &( pxQueue->xTasksWaitingToReceive ) ); } } taskEXIT_CRITICAL(); } else { xReturn = pdFAIL; } configASSERT( xReturn != pdFAIL ); /* A value is returned for calling semantic consistency with previous * versions. */ return xReturn; } /*-----------------------------------------------------------*/ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t * pucQueueStorage, StaticQueue_t * pxStaticQueue, const uint8_t ucQueueType ) { Queue_t * pxNewQueue = NULL; /* The StaticQueue_t structure and the queue storage area must be * supplied. */ configASSERT( pxStaticQueue ); if( ( uxQueueLength > ( UBaseType_t ) 0 ) && ( pxStaticQueue != NULL ) && /* A queue storage area should be provided if the item size is not 0, and * should not be provided if the item size is 0. */ ( !( ( pucQueueStorage != NULL ) && ( uxItemSize == 0 ) ) ) && ( !( ( pucQueueStorage == NULL ) && ( uxItemSize != 0 ) ) ) ) { #if ( configASSERT_DEFINED == 1 ) { /* Sanity check that the size of the structure used to declare a * variable of type StaticQueue_t or StaticSemaphore_t equals the size of * the real queue and semaphore structures. */ volatile size_t xSize = sizeof( StaticQueue_t ); /* This assertion cannot be branch covered in unit tests */ configASSERT( xSize == sizeof( Queue_t ) ); /* LCOV_EXCL_BR_LINE */ ( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */ } #endif /* configASSERT_DEFINED */ /* The address of a statically allocated queue was passed in, use it. * The address of a statically allocated storage area was also passed in * but is already set. */ pxNewQueue = ( Queue_t * ) pxStaticQueue; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) { /* Queues can be allocated wither statically or dynamically, so * note this queue was allocated statically in case the queue is * later deleted. */ pxNewQueue->ucStaticallyAllocated = pdTRUE; } #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue ); } else { configASSERT( pxNewQueue ); mtCOVERAGE_TEST_MARKER(); } return pxNewQueue; } #endif /* configSUPPORT_STATIC_ALLOCATION */ /*-----------------------------------------------------------*/ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) { Queue_t * pxNewQueue = NULL; size_t xQueueSizeInBytes; uint8_t * pucQueueStorage; if( ( uxQueueLength > ( UBaseType_t ) 0 ) && /* Check for multiplication overflow. */ ( ( SIZE_MAX / uxQueueLength ) >= uxItemSize ) && /* Check for addition overflow. */ ( ( SIZE_MAX - sizeof( Queue_t ) ) >= ( uxQueueLength * uxItemSize ) ) ) { /* Allocate enough space to hold the maximum number of items that * can be in the queue at any time. It is valid for uxItemSize to be * zero in the case the queue is used as a semaphore. */ xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ /* Allocate the queue and storage area. Justification for MISRA * deviation as follows: pvPortMalloc() always ensures returned memory * blocks are aligned per the requirements of the MCU stack. In this case * pvPortMalloc() must return a pointer that is guaranteed to meet the * alignment requirements of the Queue_t structure - which in this case * is an int8_t *. Therefore, whenever the stack alignment requirements * are greater than or equal to the pointer to char requirements the cast * is safe. In other cases alignment requirements are not strict (one or * two bytes). */ pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes ); /*lint !e9087 !e9079 see comment above. */ if( pxNewQueue != NULL ) { /* Jump past the queue structure to find the location of the queue * storage area. */ pucQueueStorage = ( uint8_t * ) pxNewQueue; pucQueueStorage += sizeof( Queue_t ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) { /* Queues can be created either statically or dynamically, so * note this task was created dynamically in case it is later * deleted. */ pxNewQueue->ucStaticallyAllocated = pdFALSE; } #endif /* configSUPPORT_STATIC_ALLOCATION */ prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue ); } else { traceQUEUE_CREATE_FAILED( ucQueueType ); mtCOVERAGE_TEST_MARKER(); } } else { configASSERT( pxNewQueue ); mtCOVERAGE_TEST_MARKER(); } return pxNewQueue; } #endif /* configSUPPORT_STATIC_ALLOCATION */ /*-----------------------------------------------------------*/ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t * pucQueueStorage, const uint8_t ucQueueType, Queue_t * pxNewQueue ) { /* Remove compiler warnings about unused parameters should * configUSE_TRACE_FACILITY not be set to 1. */ ( void ) ucQueueType; if( uxItemSize == ( UBaseType_t ) 0 ) { /* No RAM was allocated for the queue storage area, but PC head cannot * be set to NULL because NULL is used as a key to say the queue is used as * a mutex. Therefore just set pcHead to point to the queue as a benign * value that is known to be within the memory map. */ pxNewQueue->pcHead = ( int8_t * ) pxNewQueue; } else { /* Set the head to the start of the queue storage area. */ pxNewQueue->pcHead = ( int8_t * ) pucQueueStorage; } /* Initialise the queue members as described where the queue type is * defined. */ pxNewQueue->uxLength = uxQueueLength; pxNewQueue->uxItemSize = uxItemSize; ( void ) xQueueGenericReset( pxNewQueue, pdTRUE ); #if ( configUSE_TRACE_FACILITY == 1 ) { pxNewQueue->ucQueueType = ucQueueType; } #endif /* configUSE_TRACE_FACILITY */ #if ( configUSE_QUEUE_SETS == 1 ) { pxNewQueue->pxQueueSetContainer = NULL; } #endif /* configUSE_QUEUE_SETS */ traceQUEUE_CREATE( pxNewQueue ); } /*-----------------------------------------------------------*/ #if ( configUSE_MUTEXES == 1 ) static void prvInitialiseMutex( Queue_t * pxNewQueue ) { if( pxNewQueue != NULL ) { /* The queue create function will set all the queue structure members * correctly for a generic queue, but this function is creating a * mutex. Overwrite those members that need to be set differently - * in particular the information required for priority inheritance. */ pxNewQueue->u.xSemaphore.xMutexHolder = NULL; pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX; /* In case this is a recursive mutex. */ pxNewQueue->u.xSemaphore.uxRecursiveCallCount = 0; traceCREATE_MUTEX( pxNewQueue ); /* Start with the semaphore in the expected state. */ ( void ) xQueueGenericSend( pxNewQueue, NULL, ( TickType_t ) 0U, queueSEND_TO_BACK ); } else { traceCREATE_MUTEX_FAILED(); } } #endif /* configUSE_MUTEXES */ /*-----------------------------------------------------------*/ #if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) { QueueHandle_t xNewQueue; const UBaseType_t uxMutexLength = ( UBaseType_t ) 1, uxMutexSize = ( UBaseType_t ) 0; xNewQueue = xQueueGenericCreate( uxMutexLength, uxMutexSize, ucQueueType ); prvInitialiseMutex( ( Queue_t * ) xNewQueue ); return xNewQueue; } #endif /* configUSE_MUTEXES */ /*-----------------------------------------------------------*/ #if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t * pxStaticQueue ) { QueueHandle_t xNewQueue; const UBaseType_t uxMutexLength = ( UBaseType_t ) 1, uxMutexSize = ( UBaseType_t ) 0; /* Prevent compiler warnings about unused parameters if * configUSE_TRACE_FACILITY does not equal 1. */ ( void ) ucQueueType; xNewQueue = xQueueGenericCreateStatic( uxMutexLength, uxMutexSize, NULL, pxStaticQueue, ucQueueType ); prvInitialiseMutex( ( Queue_t * ) xNewQueue ); return xNewQueue; } #endif /* configUSE_MUTEXES */ /*-----------------------------------------------------------*/ #if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) TaskHandle_t xQueueGetMutexHolder( QueueHandle_t xSemaphore ) { TaskHandle_t pxReturn; Queue_t * const pxSemaphore = ( Queue_t * ) xSemaphore; configASSERT( xSemaphore ); /* This function is called by xSemaphoreGetMutexHolder(), and should not * be called directly. Note: This is a good way of determining if the * calling task is the mutex holder, but not a good way of determining the * identity of the mutex holder, as the holder may change between the * following critical section exiting and the function returning. */ taskENTER_CRITICAL(); { if( pxSemaphore->uxQueueType == queueQUEUE_IS_MUTEX ) { pxReturn = pxSemaphore->u.xSemaphore.xMutexHolder; } else { pxReturn = NULL; } } taskEXIT_CRITICAL(); return pxReturn; } /*lint !e818 xSemaphore cannot be a pointer to const because it is a typedef. */ #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) TaskHandle_t xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) { TaskHandle_t pxReturn; configASSERT( xSemaphore ); /* Mutexes cannot be used in interrupt service routines, so the mutex * holder should not change in an ISR, and therefore a critical section is * not required here. */ if( ( ( Queue_t * ) xSemaphore )->uxQueueType == queueQUEUE_IS_MUTEX ) { pxReturn = ( ( Queue_t * ) xSemaphore )->u.xSemaphore.xMutexHolder; } else { pxReturn = NULL; } return pxReturn; } /*lint !e818 xSemaphore cannot be a pointer to const because it is a typedef. */ #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( configUSE_RECURSIVE_MUTEXES == 1 ) BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) { BaseType_t xReturn; Queue_t * const pxMutex = ( Queue_t * ) xMutex; configASSERT( pxMutex ); /* If this is the task that holds the mutex then xMutexHolder will not * change outside of this task. If this task does not hold the mutex then * pxMutexHolder can never coincidentally equal the tasks handle, and as * this is the only condition we are interested in it does not matter if * pxMutexHolder is accessed simultaneously by another task. Therefore no * mutual exclusion is required to test the pxMutexHolder variable. */ if( pxMutex->u.xSemaphore.xMutexHolder == xTaskGetCurrentTaskHandle() ) { traceGIVE_MUTEX_RECURSIVE( pxMutex ); /* uxRecursiveCallCount cannot be zero if xMutexHolder is equal to * the task handle, therefore no underflow check is required. Also, * uxRecursiveCallCount is only modified by the mutex holder, and as * there can only be one, no mutual exclusion is required to modify the * uxRecursiveCallCount member. */ ( pxMutex->u.xSemaphore.uxRecursiveCallCount )--; /* Has the recursive call count unwound to 0? */ if( pxMutex->u.xSemaphore.uxRecursiveCallCount == ( UBaseType_t ) 0 ) { /* Return the mutex. This will automatically unblock any other * task that might be waiting to access the mutex. */ ( void ) xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK ); } else { mtCOVERAGE_TEST_MARKER(); } xReturn = pdPASS; } else { /* The mutex cannot be given because the calling task is not the * holder. */ xReturn = pdFAIL; traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ); } return xReturn; } #endif /* configUSE_RECURSIVE_MUTEXES */ /*-----------------------------------------------------------*/ #if ( configUSE_RECURSIVE_MUTEXES == 1 ) BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) { BaseType_t xReturn; Queue_t * const pxMutex = ( Queue_t * ) xMutex; configASSERT( pxMutex ); /* Comments regarding mutual exclusion as per those within * xQueueGiveMutexRecursive(). */ traceTAKE_MUTEX_RECURSIVE( pxMutex ); if( pxMutex->u.xSemaphore.xMutexHolder == xTaskGetCurrentTaskHandle() ) { ( pxMutex->u.xSemaphore.uxRecursiveCallCount )++; xReturn = pdPASS; } else { xReturn = xQueueSemaphoreTake( pxMutex, xTicksToWait ); /* pdPASS will only be returned if the mutex was successfully * obtained. The calling task may have entered the Blocked state * before reaching here. */ if( xReturn != pdFAIL ) { ( pxMutex->u.xSemaphore.uxRecursiveCallCount )++; } else { traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ); } } return xReturn; } #endif /* configUSE_RECURSIVE_MUTEXES */ /*-----------------------------------------------------------*/ #if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t * pxStaticQueue ) { QueueHandle_t xHandle = NULL; if( ( uxMaxCount != 0 ) && ( uxInitialCount <= uxMaxCount ) ) { xHandle = xQueueGenericCreateStatic( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticQueue, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); if( xHandle != NULL ) { ( ( Queue_t * ) xHandle )->uxMessagesWaiting = uxInitialCount; traceCREATE_COUNTING_SEMAPHORE(); } else { traceCREATE_COUNTING_SEMAPHORE_FAILED(); } } else { configASSERT( xHandle ); mtCOVERAGE_TEST_MARKER(); } return xHandle; } #endif /* ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) { QueueHandle_t xHandle = NULL; if( ( uxMaxCount != 0 ) && ( uxInitialCount <= uxMaxCount ) ) { xHandle = xQueueGenericCreate( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); if( xHandle != NULL ) { ( ( Queue_t * ) xHandle )->uxMessagesWaiting = uxInitialCount; traceCREATE_COUNTING_SEMAPHORE(); } else { traceCREATE_COUNTING_SEMAPHORE_FAILED(); } } else { configASSERT( xHandle ); mtCOVERAGE_TEST_MARKER(); } return xHandle; } #endif /* ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ /*-----------------------------------------------------------*/ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) { BaseType_t xEntryTimeSet = pdFALSE, xYieldRequired; TimeOut_t xTimeOut; Queue_t * const pxQueue = xQueue; configASSERT( pxQueue ); configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) { configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); } #endif /*lint -save -e904 This function relaxes the coding standard somewhat to * allow return statements within the function itself. This is done in the * interest of execution time efficiency. */ for( ; ; ) { taskENTER_CRITICAL(); { /* Is there room on the queue now? The running task must be the * highest priority task wanting to access the queue. If the head item * in the queue is to be overwritten then it does not matter if the * queue is full. */ if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) { traceQUEUE_SEND( pxQueue ); #if ( configUSE_QUEUE_SETS == 1 ) { const UBaseType_t uxPreviousMessagesWaiting = pxQueue->uxMessagesWaiting; xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); if( pxQueue->pxQueueSetContainer != NULL ) { if( ( xCopyPosition == queueOVERWRITE ) && ( uxPreviousMessagesWaiting != ( UBaseType_t ) 0 ) ) { /* Do not notify the queue set as an existing item * was overwritten in the queue so the number of items * in the queue has not changed. */ mtCOVERAGE_TEST_MARKER(); } else if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE ) { /* The queue is a member of a queue set, and posting * to the queue set caused a higher priority task to * unblock. A context switch is required. */ queueYIELD_IF_USING_PREEMPTION(); } else { mtCOVERAGE_TEST_MARKER(); } } else { /* If there was a task waiting for data to arrive on the * queue then unblock it now. */ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) { /* The unblocked task has a priority higher than * our own so yield immediately. Yes it is ok to * do this from within the critical section - the * kernel takes care of that. */ queueYIELD_IF_USING_PREEMPTION(); } else { mtCOVERAGE_TEST_MARKER(); } } else if( xYieldRequired != pdFALSE ) { /* This path is a special case that will only get * executed if the task was holding multiple mutexes * and the mutexes were given back in an order that is * different to that in which they were taken. */ queueYIELD_IF_USING_PREEMPTION(); } else { mtCOVERAGE_TEST_MARKER(); } } } #else /* configUSE_QUEUE_SETS */ { xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); /* If there was a task waiting for data to arrive on the * queue then unblock it now. */ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) { /* The unblocked task has a priority higher than * our own so yield immediately. Yes it is ok to do * this from within the critical section - the kernel * takes care of that. */ queueYIELD_IF_USING_PREEMPTION(); } else { mtCOVERAGE_TEST_MARKER(); } } else if( xYieldRequired != pdFALSE ) { /* This path is a special case that will only get * executed if the task was holding multiple mutexes and * the mutexes were given back in an order that is * different to that in which they were taken. */ queueYIELD_IF_USING_PREEMPTION(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* configUSE_QUEUE_SETS */ taskEXIT_CRITICAL(); return pdPASS; } else { if( xTicksToWait == ( TickType_t ) 0 ) { /* The queue was full and no block time is specified (or * the block time has expired) so leave now. */ taskEXIT_CRITICAL(); /* Return to the original privilege level before exiting * the function. */ traceQUEUE_SEND_FAILED( pxQueue ); return errQUEUE_FULL; } else if( xEntryTimeSet == pdFALSE ) { /* The queue was full and a block time was specified so * configure the timeout structure. */ vTaskInternalSetTimeOutState( &xTimeOut ); xEntryTimeSet = pdTRUE; } else { /* Entry time was already set. */ mtCOVERAGE_TEST_MARKER(); } } } taskEXIT_CRITICAL(); /* Interrupts and other tasks can send to and receive from the queue * now the critical section has been exited. */ vTaskSuspendAll(); prvLockQueue( pxQueue ); /* Update the timeout state to see if it has expired yet. */ if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) { if( prvIsQueueFull( pxQueue ) != pdFALSE ) { traceBLOCKING_ON_QUEUE_SEND( pxQueue ); vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); /* Unlocking the queue means queue events can effect the * event list. It is possible that interrupts occurring now * remove this task from the event list again - but as the * scheduler is suspended the task will go onto the pending * ready list instead of the actual ready list. */ prvUnlockQueue( pxQueue ); /* Resuming the scheduler will move tasks from the pending * ready list into the ready list - so it is feasible that this * task is already in the ready list before it yields - in which * case the yield will not cause a context switch unless there * is also a higher priority task in the pending ready list. */ if( xTaskResumeAll() == pdFALSE ) { portYIELD_WITHIN_API(); } } else { /* Try again. */ prvUnlockQueue( pxQueue ); ( void ) xTaskResumeAll(); } } else { /* The timeout has expired. */ prvUnlockQueue( pxQueue ); ( void ) xTaskResumeAll(); traceQUEUE_SEND_FAILED( pxQueue ); return errQUEUE_FULL; } } /*lint -restore */ } /*-----------------------------------------------------------*/ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t * const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition ) { BaseType_t xReturn; UBaseType_t uxSavedInterruptStatus; Queue_t * const pxQueue = xQueue; configASSERT( pxQueue ); configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); /* RTOS ports that support interrupt nesting have the concept of a maximum * system call (or maximum API call) interrupt priority. Interrupts that are * above the maximum system call priority are kept permanently enabled, even * when the RTOS kernel is in a critical section, but cannot make any calls to * FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h * then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion * failure if a FreeRTOS API function is called from an interrupt that has been * assigned a priority above the configured maximum system call priority. * Only FreeRTOS functions that end in FromISR can be called from interrupts * that have been assigned a priority at or (logically) below the maximum * system call interrupt priority. FreeRTOS maintains a separate interrupt * safe API to ensure interrupt entry is as fast and as simple as possible. * More information (albeit Cortex-M specific) is provided on the following * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); /* Similar to xQueueGenericSend, except without blocking if there is no room * in the queue. Also don't directly wake a task that was blocked on a queue * read, instead return a flag to say whether a context switch is required or * not (i.e. has a task with a higher priority than us been woken by this * post). */ uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) { const int8_t cTxLock = pxQueue->cTxLock; const UBaseType_t uxPreviousMessagesWaiting = pxQueue->uxMessagesWaiting; traceQUEUE_SEND_FROM_ISR( pxQueue ); /* Semaphores use xQueueGiveFromISR(), so pxQueue will not be a * semaphore or mutex. That means prvCopyDataToQueue() cannot result * in a task disinheriting a priority and prvCopyDataToQueue() can be * called here even though the disinherit function does not check if * the scheduler is suspended before accessing the ready lists. */ ( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); /* The event list is not altered if the queue is locked. This will * be done when the queue is unlocked later. */ if( cTxLock == queueUNLOCKED ) { #if ( configUSE_QUEUE_SETS == 1 ) { if( pxQueue->pxQueueSetContainer != NULL ) { if( ( xCopyPosition == queueOVERWRITE ) && ( uxPreviousMessagesWaiting != ( UBaseType_t ) 0 ) ) { /* Do not notify the queue set as an existing item * was overwritten in the queue so the number of items * in the queue has not changed. */ mtCOVERAGE_TEST_MARKER(); } else if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE ) { /* The queue is a member of a queue set, and posting * to the queue set caused a higher priority task to * unblock. A context switch is required. */ if( pxHigherPriorityTaskWoken != NULL ) { *pxHigherPriorityTaskWoken = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) { /* The task waiting has a higher priority so * record that a context switch is required. */ if( pxHigherPriorityTaskWoken != NULL ) { *pxHigherPriorityTaskWoken = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } } #else /* configUSE_QUEUE_SETS */ { if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) { /* The task waiting has a higher priority so record that a * context switch is required. */ if( pxHigherPriorityTaskWoken != NULL ) { *pxHigherPriorityTaskWoken = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } /* Not used in this path. */ ( void ) uxPreviousMessagesWaiting; } #endif /* configUSE_QUEUE_SETS */ } else { /* Increment the lock count so the task that unlocks the queue * knows that data was posted while it was locked. */ prvIncrementQueueTxLock( pxQueue, cTxLock ); } xReturn = pdPASS; } else { traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); xReturn = errQUEUE_FULL; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } /*-----------------------------------------------------------*/ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherPriorityTaskWoken ) { BaseType_t xReturn; UBaseType_t uxSavedInterruptStatus; Queue_t * const pxQueue = xQueue; /* Similar to xQueueGenericSendFromISR() but used with semaphores where the * item size is 0. Don't directly wake a task that was blocked on a queue * read, instead return a flag to say whether a context switch is required or * not (i.e. has a task with a higher priority than us been woken by this * post). */ configASSERT( pxQueue ); /* xQueueGenericSendFromISR() should be used instead of xQueueGiveFromISR() * if the item size is not 0. */ configASSERT( pxQueue->uxItemSize == 0 ); /* Normally a mutex would not be given from an interrupt, especially if * there is a mutex holder, as priority inheritance makes no sense for an * interrupts, only tasks. */ configASSERT( !( ( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) && ( pxQueue->u.xSemaphore.xMutexHolder != NULL ) ) ); /* RTOS ports that support interrupt nesting have the concept of a maximum * system call (or maximum API call) interrupt priority. Interrupts that are * above the maximum system call priority are kept permanently enabled, even * when the RTOS kernel is in a critical section, but cannot make any calls to * FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h * then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion * failure if a FreeRTOS API function is called from an interrupt that has been * assigned a priority above the configured maximum system call priority. * Only FreeRTOS functions that end in FromISR can be called from interrupts * that have been assigned a priority at or (logically) below the maximum * system call interrupt priority. FreeRTOS maintains a separate interrupt * safe API to ensure interrupt entry is as fast and as simple as possible. * More information (albeit Cortex-M specific) is provided on the following * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; /* When the queue is used to implement a semaphore no data is ever * moved through the queue but it is still valid to see if the queue 'has * space'. */ if( uxMessagesWaiting < pxQueue->uxLength ) { const int8_t cTxLock = pxQueue->cTxLock; traceQUEUE_SEND_FROM_ISR( pxQueue ); /* A task can only have an inherited priority if it is a mutex * holder - and if there is a mutex holder then the mutex cannot be * given from an ISR. As this is the ISR version of the function it * can be assumed there is no mutex holder and no need to determine if * priority disinheritance is needed. Simply increase the count of * messages (semaphores) available. */ pxQueue->uxMessagesWaiting = uxMessagesWaiting + ( UBaseType_t ) 1; /* The event list is not altered if the queue is locked. This will * be done when the queue is unlocked later. */ if( cTxLock == queueUNLOCKED ) { #if ( configUSE_QUEUE_SETS == 1 ) { if( pxQueue->pxQueueSetContainer != NULL ) { if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE ) { /* The semaphore is a member of a queue set, and * posting to the queue set caused a higher priority * task to unblock. A context switch is required. */ if( pxHigherPriorityTaskWoken != NULL ) { *pxHigherPriorityTaskWoken = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) { /* The task waiting has a higher priority so * record that a context switch is required. */ if( pxHigherPriorityTaskWoken != NULL ) { *pxHigherPriorityTaskWoken = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } } #else /* configUSE_QUEUE_SETS */ { if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) { /* The task waiting has a higher priority so record that a * context switch is required. */ if( pxHigherPriorityTaskWoken != NULL ) { *pxHigherPriorityTaskWoken = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* configUSE_QUEUE_SETS */ } else { /* Increment the lock count so the task that unlocks the queue * knows that data was posted while it was locked. */ prvIncrementQueueTxLock( pxQueue, cTxLock ); } xReturn = pdPASS; } else { traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); xReturn = errQUEUE_FULL; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } /*-----------------------------------------------------------*/ BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) { BaseType_t xEntryTimeSet = pdFALSE; TimeOut_t xTimeOut; Queue_t * const pxQueue = xQueue; /* Check the pointer is not NULL. */ configASSERT( ( pxQueue ) ); /* The buffer into which data is received can only be NULL if the data size * is zero (so no data is copied into the buffer). */ configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) ); /* Cannot block if the scheduler is suspended. */ #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) { configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); } #endif /*lint -save -e904 This function relaxes the coding standard somewhat to * allow return statements within the function itself. This is done in the * interest of execution time efficiency. */ for( ; ; ) { taskENTER_CRITICAL(); { const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; /* Is there data in the queue now? To be running the calling task * must be the highest priority task wanting to access the queue. */ if( uxMessagesWaiting > ( UBaseType_t ) 0 ) { /* Data available, remove one item. */ prvCopyDataFromQueue( pxQueue, pvBuffer ); traceQUEUE_RECEIVE( pxQueue ); pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1; /* There is now space in the queue, were any tasks waiting to * post to the queue? If so, unblock the highest priority waiting * task. */ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) { queueYIELD_IF_USING_PREEMPTION(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } taskEXIT_CRITICAL(); return pdPASS; } else { if( xTicksToWait == ( TickType_t ) 0 ) { /* The queue was empty and no block time is specified (or * the block time has expired) so leave now. */ taskEXIT_CRITICAL(); traceQUEUE_RECEIVE_FAILED( pxQueue ); return errQUEUE_EMPTY; } else if( xEntryTimeSet == pdFALSE ) { /* The queue was empty and a block time was specified so * configure the timeout structure. */ vTaskInternalSetTimeOutState( &xTimeOut ); xEntryTimeSet = pdTRUE; } else { /* Entry time was already set. */ mtCOVERAGE_TEST_MARKER(); } } } taskEXIT_CRITICAL(); /* Interrupts and other tasks can send to and receive from the queue * now the critical section has been exited. */ vTaskSuspendAll(); prvLockQueue( pxQueue ); /* Update the timeout state to see if it has expired yet. */ if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) { /* The timeout has not expired. If the queue is still empty place * the task on the list of tasks waiting to receive from the queue. */ if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) { traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); prvUnlockQueue( pxQueue ); if( xTaskResumeAll() == pdFALSE ) { portYIELD_WITHIN_API(); } else { mtCOVERAGE_TEST_MARKER(); } } else { /* The queue contains data again. Loop back to try and read the * data. */ prvUnlockQueue( pxQueue ); ( void ) xTaskResumeAll(); } } else { /* Timed out. If there is no data in the queue exit, otherwise loop * back and attempt to read the data. */ prvUnlockQueue( pxQueue ); ( void ) xTaskResumeAll(); if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) { traceQUEUE_RECEIVE_FAILED( pxQueue ); return errQUEUE_EMPTY; } else { mtCOVERAGE_TEST_MARKER(); } } } /*lint -restore */ } /*-----------------------------------------------------------*/ BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) { BaseType_t xEntryTimeSet = pdFALSE; TimeOut_t xTimeOut; Queue_t * const pxQueue = xQueue; #if ( configUSE_MUTEXES == 1 ) BaseType_t xInheritanceOccurred = pdFALSE; #endif /* Check the queue pointer is not NULL. */ configASSERT( ( pxQueue ) ); /* Check this really is a semaphore, in which case the item size will be * 0. */ configASSERT( pxQueue->uxItemSize == 0 ); /* Cannot block if the scheduler is suspended. */ #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) { configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); } #endif /*lint -save -e904 This function relaxes the coding standard somewhat to allow return * statements within the function itself. This is done in the interest * of execution time efficiency. */ for( ; ; ) { taskENTER_CRITICAL(); { /* Semaphores are queues with an item size of 0, and where the * number of messages in the queue is the semaphore's count value. */ const UBaseType_t uxSemaphoreCount = pxQueue->uxMessagesWaiting; /* Is there data in the queue now? To be running the calling task * must be the highest priority task wanting to access the queue. */ if( uxSemaphoreCount > ( UBaseType_t ) 0 ) { traceQUEUE_RECEIVE( pxQueue ); /* Semaphores are queues with a data size of zero and where the * messages waiting is the semaphore's count. Reduce the count. */ pxQueue->uxMessagesWaiting = uxSemaphoreCount - ( UBaseType_t ) 1; #if ( configUSE_MUTEXES == 1 ) { if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) { /* Record the information required to implement * priority inheritance should it become necessary. */ pxQueue->u.xSemaphore.xMutexHolder = pvTaskIncrementMutexHeldCount(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* configUSE_MUTEXES */ /* Check to see if other tasks are blocked waiting to give the * semaphore, and if so, unblock the highest priority such task. */ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) { queueYIELD_IF_USING_PREEMPTION(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } taskEXIT_CRITICAL(); return pdPASS; } else { if( xTicksToWait == ( TickType_t ) 0 ) { /* The semaphore count was 0 and no block time is specified * (or the block time has expired) so exit now. */ taskEXIT_CRITICAL(); traceQUEUE_RECEIVE_FAILED( pxQueue ); return errQUEUE_EMPTY; } else if( xEntryTimeSet == pdFALSE ) { /* The semaphore count was 0 and a block time was specified * so configure the timeout structure ready to block. */ vTaskInternalSetTimeOutState( &xTimeOut ); xEntryTimeSet = pdTRUE; } else { /* Entry time was already set. */ mtCOVERAGE_TEST_MARKER(); } } } taskEXIT_CRITICAL(); /* Interrupts and other tasks can give to and take from the semaphore * now the critical section has been exited. */ vTaskSuspendAll(); prvLockQueue( pxQueue ); /* Update the timeout state to see if it has expired yet. */ if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) { /* A block time is specified and not expired. If the semaphore * count is 0 then enter the Blocked state to wait for a semaphore to * become available. As semaphores are implemented with queues the * queue being empty is equivalent to the semaphore count being 0. */ if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) { traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); #if ( configUSE_MUTEXES == 1 ) { if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) { taskENTER_CRITICAL(); { xInheritanceOccurred = xTaskPriorityInherit( pxQueue->u.xSemaphore.xMutexHolder ); } taskEXIT_CRITICAL(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* if ( configUSE_MUTEXES == 1 ) */ vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); prvUnlockQueue( pxQueue ); if( xTaskResumeAll() == pdFALSE ) { portYIELD_WITHIN_API(); } else { mtCOVERAGE_TEST_MARKER(); } } else { /* There was no timeout and the semaphore count was not 0, so * attempt to take the semaphore again. */ prvUnlockQueue( pxQueue ); ( void ) xTaskResumeAll(); } } else { /* Timed out. */ prvUnlockQueue( pxQueue ); ( void ) xTaskResumeAll(); /* If the semaphore count is 0 exit now as the timeout has * expired. Otherwise return to attempt to take the semaphore that is * known to be available. As semaphores are implemented by queues the * queue being empty is equivalent to the semaphore count being 0. */ if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) { #if ( configUSE_MUTEXES == 1 ) { /* xInheritanceOccurred could only have be set if * pxQueue->uxQueueType == queueQUEUE_IS_MUTEX so no need to * test the mutex type again to check it is actually a mutex. */ if( xInheritanceOccurred != pdFALSE ) { taskENTER_CRITICAL(); { UBaseType_t uxHighestWaitingPriority; /* This task blocking on the mutex caused another * task to inherit this task's priority. Now this task * has timed out the priority should be disinherited * again, but only as low as the next highest priority * task that is waiting for the same mutex. */ uxHighestWaitingPriority = prvGetDisinheritPriorityAfterTimeout( pxQueue ); vTaskPriorityDisinheritAfterTimeout( pxQueue->u.xSemaphore.xMutexHolder, uxHighestWaitingPriority ); } taskEXIT_CRITICAL(); } } #endif /* configUSE_MUTEXES */ traceQUEUE_RECEIVE_FAILED( pxQueue ); return errQUEUE_EMPTY; } else { mtCOVERAGE_TEST_MARKER(); } } } /*lint -restore */ } /*-----------------------------------------------------------*/ BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) { BaseType_t xEntryTimeSet = pdFALSE; TimeOut_t xTimeOut; int8_t * pcOriginalReadPosition; Queue_t * const pxQueue = xQueue; /* Check the pointer is not NULL. */ configASSERT( ( pxQueue ) ); /* The buffer into which data is received can only be NULL if the data size * is zero (so no data is copied into the buffer. */ configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) ); /* Cannot block if the scheduler is suspended. */ #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) { configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); } #endif /*lint -save -e904 This function relaxes the coding standard somewhat to * allow return statements within the function itself. This is done in the * interest of execution time efficiency. */ for( ; ; ) { taskENTER_CRITICAL(); { const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; /* Is there data in the queue now? To be running the calling task * must be the highest priority task wanting to access the queue. */ if( uxMessagesWaiting > ( UBaseType_t ) 0 ) { /* Remember the read position so it can be reset after the data * is read from the queue as this function is only peeking the * data, not removing it. */ pcOriginalReadPosition = pxQueue->u.xQueue.pcReadFrom; prvCopyDataFromQueue( pxQueue, pvBuffer ); traceQUEUE_PEEK( pxQueue ); /* The data is not being removed, so reset the read pointer. */ pxQueue->u.xQueue.pcReadFrom = pcOriginalReadPosition; /* The data is being left in the queue, so see if there are * any other tasks waiting for the data. */ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) { /* The task waiting has a higher priority than this task. */ queueYIELD_IF_USING_PREEMPTION(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } taskEXIT_CRITICAL(); return pdPASS; } else { if( xTicksToWait == ( TickType_t ) 0 ) { /* The queue was empty and no block time is specified (or * the block time has expired) so leave now. */ taskEXIT_CRITICAL(); traceQUEUE_PEEK_FAILED( pxQueue ); return errQUEUE_EMPTY; } else if( xEntryTimeSet == pdFALSE ) { /* The queue was empty and a block time was specified so * configure the timeout structure ready to enter the blocked * state. */ vTaskInternalSetTimeOutState( &xTimeOut ); xEntryTimeSet = pdTRUE; } else { /* Entry time was already set. */ mtCOVERAGE_TEST_MARKER(); } } } taskEXIT_CRITICAL(); /* Interrupts and other tasks can send to and receive from the queue * now that the critical section has been exited. */ vTaskSuspendAll(); prvLockQueue( pxQueue ); /* Update the timeout state to see if it has expired yet. */ if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) { /* Timeout has not expired yet, check to see if there is data in the * queue now, and if not enter the Blocked state to wait for data. */ if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) { traceBLOCKING_ON_QUEUE_PEEK( pxQueue ); vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); prvUnlockQueue( pxQueue ); if( xTaskResumeAll() == pdFALSE ) { portYIELD_WITHIN_API(); } else { mtCOVERAGE_TEST_MARKER(); } } else { /* There is data in the queue now, so don't enter the blocked * state, instead return to try and obtain the data. */ prvUnlockQueue( pxQueue ); ( void ) xTaskResumeAll(); } } else { /* The timeout has expired. If there is still no data in the queue * exit, otherwise go back and try to read the data again. */ prvUnlockQueue( pxQueue ); ( void ) xTaskResumeAll(); if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) { traceQUEUE_PEEK_FAILED( pxQueue ); return errQUEUE_EMPTY; } else { mtCOVERAGE_TEST_MARKER(); } } } /*lint -restore */ } /*-----------------------------------------------------------*/ BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) { BaseType_t xReturn; UBaseType_t uxSavedInterruptStatus; Queue_t * const pxQueue = xQueue; configASSERT( pxQueue ); configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); /* RTOS ports that support interrupt nesting have the concept of a maximum * system call (or maximum API call) interrupt priority. Interrupts that are * above the maximum system call priority are kept permanently enabled, even * when the RTOS kernel is in a critical section, but cannot make any calls to * FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h * then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion * failure if a FreeRTOS API function is called from an interrupt that has been * assigned a priority above the configured maximum system call priority. * Only FreeRTOS functions that end in FromISR can be called from interrupts * that have been assigned a priority at or (logically) below the maximum * system call interrupt priority. FreeRTOS maintains a separate interrupt * safe API to ensure interrupt entry is as fast and as simple as possible. * More information (albeit Cortex-M specific) is provided on the following * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; /* Cannot block in an ISR, so check there is data available. */ if( uxMessagesWaiting > ( UBaseType_t ) 0 ) { const int8_t cRxLock = pxQueue->cRxLock; traceQUEUE_RECEIVE_FROM_ISR( pxQueue ); prvCopyDataFromQueue( pxQueue, pvBuffer ); pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1; /* If the queue is locked the event list will not be modified. * Instead update the lock count so the task that unlocks the queue * will know that an ISR has removed data while the queue was * locked. */ if( cRxLock == queueUNLOCKED ) { if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) { /* The task waiting has a higher priority than us so * force a context switch. */ if( pxHigherPriorityTaskWoken != NULL ) { *pxHigherPriorityTaskWoken = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { /* Increment the lock count so the task that unlocks the queue * knows that data was removed while it was locked. */ prvIncrementQueueRxLock( pxQueue, cRxLock ); } xReturn = pdPASS; } else { xReturn = pdFAIL; traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ); } } portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } /*-----------------------------------------------------------*/ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) { BaseType_t xReturn; UBaseType_t uxSavedInterruptStatus; int8_t * pcOriginalReadPosition; Queue_t * const pxQueue = xQueue; configASSERT( pxQueue ); configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); configASSERT( pxQueue->uxItemSize != 0 ); /* Can't peek a semaphore. */ /* RTOS ports that support interrupt nesting have the concept of a maximum * system call (or maximum API call) interrupt priority. Interrupts that are * above the maximum system call priority are kept permanently enabled, even * when the RTOS kernel is in a critical section, but cannot make any calls to * FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h * then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion * failure if a FreeRTOS API function is called from an interrupt that has been * assigned a priority above the configured maximum system call priority. * Only FreeRTOS functions that end in FromISR can be called from interrupts * that have been assigned a priority at or (logically) below the maximum * system call interrupt priority. FreeRTOS maintains a separate interrupt * safe API to ensure interrupt entry is as fast and as simple as possible. * More information (albeit Cortex-M specific) is provided on the following * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Cannot block in an ISR, so check there is data available. */ if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) { traceQUEUE_PEEK_FROM_ISR( pxQueue ); /* Remember the read position so it can be reset as nothing is * actually being removed from the queue. */ pcOriginalReadPosition = pxQueue->u.xQueue.pcReadFrom; prvCopyDataFromQueue( pxQueue, pvBuffer ); pxQueue->u.xQueue.pcReadFrom = pcOriginalReadPosition; xReturn = pdPASS; } else { xReturn = pdFAIL; traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ); } } portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } /*-----------------------------------------------------------*/ UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) { UBaseType_t uxReturn; configASSERT( xQueue ); taskENTER_CRITICAL(); { uxReturn = ( ( Queue_t * ) xQueue )->uxMessagesWaiting; } taskEXIT_CRITICAL(); return uxReturn; } /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ /*-----------------------------------------------------------*/ UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) { UBaseType_t uxReturn; Queue_t * const pxQueue = xQueue; configASSERT( pxQueue ); taskENTER_CRITICAL(); { uxReturn = pxQueue->uxLength - pxQueue->uxMessagesWaiting; } taskEXIT_CRITICAL(); return uxReturn; } /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ /*-----------------------------------------------------------*/ UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) { UBaseType_t uxReturn; Queue_t * const pxQueue = xQueue; configASSERT( pxQueue ); uxReturn = pxQueue->uxMessagesWaiting; return uxReturn; } /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ /*-----------------------------------------------------------*/ void vQueueDelete( QueueHandle_t xQueue ) { Queue_t * const pxQueue = xQueue; configASSERT( pxQueue ); traceQUEUE_DELETE( pxQueue ); #if ( configQUEUE_REGISTRY_SIZE > 0 ) { vQueueUnregisterQueue( pxQueue ); } #endif #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) { /* The queue can only have been allocated dynamically - free it * again. */ vPortFree( pxQueue ); } #elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) { /* The queue could have been allocated statically or dynamically, so * check before attempting to free the memory. */ if( pxQueue->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) { vPortFree( pxQueue ); } else { mtCOVERAGE_TEST_MARKER(); } } #else /* if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) */ { /* The queue must have been statically allocated, so is not going to be * deleted. Avoid compiler warnings about the unused parameter. */ ( void ) pxQueue; } #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ } /*-----------------------------------------------------------*/ #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) { return ( ( Queue_t * ) xQueue )->uxQueueNumber; } #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ #if ( configUSE_TRACE_FACILITY == 1 ) void vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) { ( ( Queue_t * ) xQueue )->uxQueueNumber = uxQueueNumber; } #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ #if ( configUSE_TRACE_FACILITY == 1 ) uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) { return ( ( Queue_t * ) xQueue )->ucQueueType; } #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ #if ( configUSE_MUTEXES == 1 ) static UBaseType_t prvGetDisinheritPriorityAfterTimeout( const Queue_t * const pxQueue ) { UBaseType_t uxHighestPriorityOfWaitingTasks; /* If a task waiting for a mutex causes the mutex holder to inherit a * priority, but the waiting task times out, then the holder should * disinherit the priority - but only down to the highest priority of any * other tasks that are waiting for the same mutex. For this purpose, * return the priority of the highest priority task that is waiting for the * mutex. */ if( listCURRENT_LIST_LENGTH( &( pxQueue->xTasksWaitingToReceive ) ) > 0U ) { uxHighestPriorityOfWaitingTasks = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) listGET_ITEM_VALUE_OF_HEAD_ENTRY( &( pxQueue->xTasksWaitingToReceive ) ); } else { uxHighestPriorityOfWaitingTasks = tskIDLE_PRIORITY; } return uxHighestPriorityOfWaitingTasks; } #endif /* configUSE_MUTEXES */ /*-----------------------------------------------------------*/ static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void * pvItemToQueue, const BaseType_t xPosition ) { BaseType_t xReturn = pdFALSE; UBaseType_t uxMessagesWaiting; /* This function is called from a critical section. */ uxMessagesWaiting = pxQueue->uxMessagesWaiting; if( pxQueue->uxItemSize == ( UBaseType_t ) 0 ) { #if ( configUSE_MUTEXES == 1 ) { if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) { /* The mutex is no longer being held. */ xReturn = xTaskPriorityDisinherit( pxQueue->u.xSemaphore.xMutexHolder ); pxQueue->u.xSemaphore.xMutexHolder = NULL; } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* configUSE_MUTEXES */ } else if( xPosition == queueSEND_TO_BACK ) { ( void ) memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports, plus previous logic ensures a null pointer can only be passed to memcpy() if the copy size is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */ pxQueue->pcWriteTo += pxQueue->uxItemSize; /*lint !e9016 Pointer arithmetic on char types ok, especially in this use case where it is the clearest way of conveying intent. */ if( pxQueue->pcWriteTo >= pxQueue->u.xQueue.pcTail ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ { pxQueue->pcWriteTo = pxQueue->pcHead; } else { mtCOVERAGE_TEST_MARKER(); } } else { ( void ) memcpy( ( void * ) pxQueue->u.xQueue.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e9087 !e418 MISRA exception as the casts are only redundant for some ports. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. Assert checks null pointer only used when length is 0. */ pxQueue->u.xQueue.pcReadFrom -= pxQueue->uxItemSize; if( pxQueue->u.xQueue.pcReadFrom < pxQueue->pcHead ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ { pxQueue->u.xQueue.pcReadFrom = ( pxQueue->u.xQueue.pcTail - pxQueue->uxItemSize ); } else { mtCOVERAGE_TEST_MARKER(); } if( xPosition == queueOVERWRITE ) { if( uxMessagesWaiting > ( UBaseType_t ) 0 ) { /* An item is not being added but overwritten, so subtract * one from the recorded number of items in the queue so when * one is added again below the number of recorded items remains * correct. */ --uxMessagesWaiting; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } pxQueue->uxMessagesWaiting = uxMessagesWaiting + ( UBaseType_t ) 1; return xReturn; } /*-----------------------------------------------------------*/ static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer ) { if( pxQueue->uxItemSize != ( UBaseType_t ) 0 ) { pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; /*lint !e9016 Pointer arithmetic on char types ok, especially in this use case where it is the clearest way of conveying intent. */ if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) /*lint !e946 MISRA exception justified as use of the relational operator is the cleanest solutions. */ { pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; } else { mtCOVERAGE_TEST_MARKER(); } ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */ } } /*-----------------------------------------------------------*/ static void prvUnlockQueue( Queue_t * const pxQueue ) { /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */ /* The lock counts contains the number of extra data items placed or * removed from the queue while the queue was locked. When a queue is * locked items can be added or removed, but the event lists cannot be * updated. */ taskENTER_CRITICAL(); { int8_t cTxLock = pxQueue->cTxLock; /* See if data was added to the queue while it was locked. */ while( cTxLock > queueLOCKED_UNMODIFIED ) { /* Data was posted while the queue was locked. Are any tasks * blocked waiting for data to become available? */ #if ( configUSE_QUEUE_SETS == 1 ) { if( pxQueue->pxQueueSetContainer != NULL ) { if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE ) { /* The queue is a member of a queue set, and posting to * the queue set caused a higher priority task to unblock. * A context switch is required. */ vTaskMissedYield(); } else { mtCOVERAGE_TEST_MARKER(); } } else { /* Tasks that are removed from the event list will get * added to the pending ready list as the scheduler is still * suspended. */ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) { /* The task waiting has a higher priority so record that a * context switch is required. */ vTaskMissedYield(); } else { mtCOVERAGE_TEST_MARKER(); } } else { break; } } } #else /* configUSE_QUEUE_SETS */ { /* Tasks that are removed from the event list will get added to * the pending ready list as the scheduler is still suspended. */ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) { /* The task waiting has a higher priority so record that * a context switch is required. */ vTaskMissedYield(); } else { mtCOVERAGE_TEST_MARKER(); } } else { break; } } #endif /* configUSE_QUEUE_SETS */ --cTxLock; } pxQueue->cTxLock = queueUNLOCKED; } taskEXIT_CRITICAL(); /* Do the same for the Rx lock. */ taskENTER_CRITICAL(); { int8_t cRxLock = pxQueue->cRxLock; while( cRxLock > queueLOCKED_UNMODIFIED ) { if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) { vTaskMissedYield(); } else { mtCOVERAGE_TEST_MARKER(); } --cRxLock; } else { break; } } pxQueue->cRxLock = queueUNLOCKED; } taskEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ static BaseType_t prvIsQueueEmpty( const Queue_t * pxQueue ) { BaseType_t xReturn; taskENTER_CRITICAL(); { if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) { xReturn = pdTRUE; } else { xReturn = pdFALSE; } } taskEXIT_CRITICAL(); return xReturn; } /*-----------------------------------------------------------*/ BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) { BaseType_t xReturn; Queue_t * const pxQueue = xQueue; configASSERT( pxQueue ); if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) { xReturn = pdTRUE; } else { xReturn = pdFALSE; } return xReturn; } /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ /*-----------------------------------------------------------*/ static BaseType_t prvIsQueueFull( const Queue_t * pxQueue ) { BaseType_t xReturn; taskENTER_CRITICAL(); { if( pxQueue->uxMessagesWaiting == pxQueue->uxLength ) { xReturn = pdTRUE; } else { xReturn = pdFALSE; } } taskEXIT_CRITICAL(); return xReturn; } /*-----------------------------------------------------------*/ BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) { BaseType_t xReturn; Queue_t * const pxQueue = xQueue; configASSERT( pxQueue ); if( pxQueue->uxMessagesWaiting == pxQueue->uxLength ) { xReturn = pdTRUE; } else { xReturn = pdFALSE; } return xReturn; } /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ /*-----------------------------------------------------------*/ #if ( configUSE_CO_ROUTINES == 1 ) BaseType_t xQueueCRSend( QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait ) { BaseType_t xReturn; Queue_t * const pxQueue = xQueue; /* If the queue is already full we may have to block. A critical section * is required to prevent an interrupt removing something from the queue * between the check to see if the queue is full and blocking on the queue. */ portDISABLE_INTERRUPTS(); { if( prvIsQueueFull( pxQueue ) != pdFALSE ) { /* The queue is full - do we want to block or just leave without * posting? */ if( xTicksToWait > ( TickType_t ) 0 ) { /* As this is called from a coroutine we cannot block directly, but * return indicating that we need to block. */ vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) ); portENABLE_INTERRUPTS(); return errQUEUE_BLOCKED; } else { portENABLE_INTERRUPTS(); return errQUEUE_FULL; } } } portENABLE_INTERRUPTS(); portDISABLE_INTERRUPTS(); { if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) { /* There is room in the queue, copy the data into the queue. */ prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); xReturn = pdPASS; /* Were any co-routines waiting for data to become available? */ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) { /* In this instance the co-routine could be placed directly * into the ready list as we are within a critical section. * Instead the same pending ready list mechanism is used as if * the event were caused from within an interrupt. */ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) { /* The co-routine waiting has a higher priority so record * that a yield might be appropriate. */ xReturn = errQUEUE_YIELD; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { xReturn = errQUEUE_FULL; } } portENABLE_INTERRUPTS(); return xReturn; } #endif /* configUSE_CO_ROUTINES */ /*-----------------------------------------------------------*/ #if ( configUSE_CO_ROUTINES == 1 ) BaseType_t xQueueCRReceive( QueueHandle_t xQueue, void * pvBuffer, TickType_t xTicksToWait ) { BaseType_t xReturn; Queue_t * const pxQueue = xQueue; /* If the queue is already empty we may have to block. A critical section * is required to prevent an interrupt adding something to the queue * between the check to see if the queue is empty and blocking on the queue. */ portDISABLE_INTERRUPTS(); { if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) { /* There are no messages in the queue, do we want to block or just * leave with nothing? */ if( xTicksToWait > ( TickType_t ) 0 ) { /* As this is a co-routine we cannot block directly, but return * indicating that we need to block. */ vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) ); portENABLE_INTERRUPTS(); return errQUEUE_BLOCKED; } else { portENABLE_INTERRUPTS(); return errQUEUE_FULL; } } else { mtCOVERAGE_TEST_MARKER(); } } portENABLE_INTERRUPTS(); portDISABLE_INTERRUPTS(); { if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) { /* Data is available from the queue. */ pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) { pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; } else { mtCOVERAGE_TEST_MARKER(); } --( pxQueue->uxMessagesWaiting ); ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); xReturn = pdPASS; /* Were any co-routines waiting for space to become available? */ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) { /* In this instance the co-routine could be placed directly * into the ready list as we are within a critical section. * Instead the same pending ready list mechanism is used as if * the event were caused from within an interrupt. */ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) { xReturn = errQUEUE_YIELD; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { xReturn = pdFAIL; } } portENABLE_INTERRUPTS(); return xReturn; } #endif /* configUSE_CO_ROUTINES */ /*-----------------------------------------------------------*/ #if ( configUSE_CO_ROUTINES == 1 ) BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t xCoRoutinePreviouslyWoken ) { Queue_t * const pxQueue = xQueue; /* Cannot block within an ISR so if there is no space on the queue then * exit without doing anything. */ if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) { prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); /* We only want to wake one co-routine per ISR, so check that a * co-routine has not already been woken. */ if( xCoRoutinePreviouslyWoken == pdFALSE ) { if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) { if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) { return pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } return xCoRoutinePreviouslyWoken; } #endif /* configUSE_CO_ROUTINES */ /*-----------------------------------------------------------*/ #if ( configUSE_CO_ROUTINES == 1 ) BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, void * pvBuffer, BaseType_t * pxCoRoutineWoken ) { BaseType_t xReturn; Queue_t * const pxQueue = xQueue; /* We cannot block from an ISR, so check there is data available. If * not then just leave without doing anything. */ if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) { /* Copy the data from the queue. */ pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) { pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; } else { mtCOVERAGE_TEST_MARKER(); } --( pxQueue->uxMessagesWaiting ); ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); if( ( *pxCoRoutineWoken ) == pdFALSE ) { if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) { if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) { *pxCoRoutineWoken = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } xReturn = pdPASS; } else { xReturn = pdFAIL; } return xReturn; } #endif /* configUSE_CO_ROUTINES */ /*-----------------------------------------------------------*/ #if ( configQUEUE_REGISTRY_SIZE > 0 ) void vQueueAddToRegistry( QueueHandle_t xQueue, const char * pcQueueName ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ { UBaseType_t ux; QueueRegistryItem_t * pxEntryToWrite = NULL; configASSERT( xQueue ); if( pcQueueName != NULL ) { /* See if there is an empty space in the registry. A NULL name denotes * a free slot. */ for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) { /* Replace an existing entry if the queue is already in the registry. */ if( xQueue == xQueueRegistry[ ux ].xHandle ) { pxEntryToWrite = &( xQueueRegistry[ ux ] ); break; } /* Otherwise, store in the next empty location */ else if( ( pxEntryToWrite == NULL ) && ( xQueueRegistry[ ux ].pcQueueName == NULL ) ) { pxEntryToWrite = &( xQueueRegistry[ ux ] ); } else { mtCOVERAGE_TEST_MARKER(); } } } if( pxEntryToWrite != NULL ) { /* Store the information on this queue. */ pxEntryToWrite->pcQueueName = pcQueueName; pxEntryToWrite->xHandle = xQueue; traceQUEUE_REGISTRY_ADD( xQueue, pcQueueName ); } } #endif /* configQUEUE_REGISTRY_SIZE */ /*-----------------------------------------------------------*/ #if ( configQUEUE_REGISTRY_SIZE > 0 ) const char * pcQueueGetName( QueueHandle_t xQueue ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ { UBaseType_t ux; const char * pcReturn = NULL; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ configASSERT( xQueue ); /* Note there is nothing here to protect against another task adding or * removing entries from the registry while it is being searched. */ for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) { if( xQueueRegistry[ ux ].xHandle == xQueue ) { pcReturn = xQueueRegistry[ ux ].pcQueueName; break; } else { mtCOVERAGE_TEST_MARKER(); } } return pcReturn; } /*lint !e818 xQueue cannot be a pointer to const because it is a typedef. */ #endif /* configQUEUE_REGISTRY_SIZE */ /*-----------------------------------------------------------*/ #if ( configQUEUE_REGISTRY_SIZE > 0 ) void vQueueUnregisterQueue( QueueHandle_t xQueue ) { UBaseType_t ux; configASSERT( xQueue ); /* See if the handle of the queue being unregistered in actually in the * registry. */ for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) { if( xQueueRegistry[ ux ].xHandle == xQueue ) { /* Set the name to NULL to show that this slot if free again. */ xQueueRegistry[ ux ].pcQueueName = NULL; /* Set the handle to NULL to ensure the same queue handle cannot * appear in the registry twice if it is added, removed, then * added again. */ xQueueRegistry[ ux ].xHandle = ( QueueHandle_t ) 0; break; } else { mtCOVERAGE_TEST_MARKER(); } } } /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ #endif /* configQUEUE_REGISTRY_SIZE */ /*-----------------------------------------------------------*/ #if ( configUSE_TIMERS == 1 ) void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) { Queue_t * const pxQueue = xQueue; /* This function should not be called by application code hence the * 'Restricted' in its name. It is not part of the public API. It is * designed for use by kernel code, and has special calling requirements. * It can result in vListInsert() being called on a list that can only * possibly ever have one item in it, so the list will be fast, but even * so it should be called with the scheduler locked and not from a critical * section. */ /* Only do anything if there are no messages in the queue. This function * will not actually cause the task to block, just place it on a blocked * list. It will not block until the scheduler is unlocked - at which * time a yield will be performed. If an item is added to the queue while * the queue is locked, and the calling task blocks on the queue, then the * calling task will be immediately unblocked when the queue is unlocked. */ prvLockQueue( pxQueue ); if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0U ) { /* There is nothing in the queue, block for the specified period. */ vTaskPlaceOnEventListRestricted( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait, xWaitIndefinitely ); } else { mtCOVERAGE_TEST_MARKER(); } prvUnlockQueue( pxQueue ); } #endif /* configUSE_TIMERS */ /*-----------------------------------------------------------*/ #if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) { QueueSetHandle_t pxQueue; pxQueue = xQueueGenericCreate( uxEventQueueLength, ( UBaseType_t ) sizeof( Queue_t * ), queueQUEUE_TYPE_SET ); return pxQueue; } #endif /* configUSE_QUEUE_SETS */ /*-----------------------------------------------------------*/ #if ( configUSE_QUEUE_SETS == 1 ) BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) { BaseType_t xReturn; taskENTER_CRITICAL(); { if( ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL ) { /* Cannot add a queue/semaphore to more than one queue set. */ xReturn = pdFAIL; } else if( ( ( Queue_t * ) xQueueOrSemaphore )->uxMessagesWaiting != ( UBaseType_t ) 0 ) { /* Cannot add a queue/semaphore to a queue set if there are already * items in the queue/semaphore. */ xReturn = pdFAIL; } else { ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer = xQueueSet; xReturn = pdPASS; } } taskEXIT_CRITICAL(); return xReturn; } #endif /* configUSE_QUEUE_SETS */ /*-----------------------------------------------------------*/ #if ( configUSE_QUEUE_SETS == 1 ) BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) { BaseType_t xReturn; Queue_t * const pxQueueOrSemaphore = ( Queue_t * ) xQueueOrSemaphore; if( pxQueueOrSemaphore->pxQueueSetContainer != xQueueSet ) { /* The queue was not a member of the set. */ xReturn = pdFAIL; } else if( pxQueueOrSemaphore->uxMessagesWaiting != ( UBaseType_t ) 0 ) { /* It is dangerous to remove a queue from a set when the queue is * not empty because the queue set will still hold pending events for * the queue. */ xReturn = pdFAIL; } else { taskENTER_CRITICAL(); { /* The queue is no longer contained in the set. */ pxQueueOrSemaphore->pxQueueSetContainer = NULL; } taskEXIT_CRITICAL(); xReturn = pdPASS; } return xReturn; } /*lint !e818 xQueueSet could not be declared as pointing to const as it is a typedef. */ #endif /* configUSE_QUEUE_SETS */ /*-----------------------------------------------------------*/ #if ( configUSE_QUEUE_SETS == 1 ) QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t const xTicksToWait ) { QueueSetMemberHandle_t xReturn = NULL; ( void ) xQueueReceive( ( QueueHandle_t ) xQueueSet, &xReturn, xTicksToWait ); /*lint !e961 Casting from one typedef to another is not redundant. */ return xReturn; } #endif /* configUSE_QUEUE_SETS */ /*-----------------------------------------------------------*/ #if ( configUSE_QUEUE_SETS == 1 ) QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) { QueueSetMemberHandle_t xReturn = NULL; ( void ) xQueueReceiveFromISR( ( QueueHandle_t ) xQueueSet, &xReturn, NULL ); /*lint !e961 Casting from one typedef to another is not redundant. */ return xReturn; } #endif /* configUSE_QUEUE_SETS */ /*-----------------------------------------------------------*/ #if ( configUSE_QUEUE_SETS == 1 ) static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue ) { Queue_t * pxQueueSetContainer = pxQueue->pxQueueSetContainer; BaseType_t xReturn = pdFALSE; /* This function must be called form a critical section. */ /* The following line is not reachable in unit tests because every call * to prvNotifyQueueSetContainer is preceded by a check that * pxQueueSetContainer != NULL */ configASSERT( pxQueueSetContainer ); /* LCOV_EXCL_BR_LINE */ configASSERT( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ); if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ) { const int8_t cTxLock = pxQueueSetContainer->cTxLock; traceQUEUE_SET_SEND( pxQueueSetContainer ); /* The data copied is the handle of the queue that contains data. */ xReturn = prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, queueSEND_TO_BACK ); if( cTxLock == queueUNLOCKED ) { if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE ) { /* The task waiting has a higher priority. */ xReturn = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { prvIncrementQueueTxLock( pxQueueSetContainer, cTxLock ); } } else { mtCOVERAGE_TEST_MARKER(); } return xReturn; } #endif /* configUSE_QUEUE_SETS */ ================================================ FILE: FreeRTOS-comparison/sbom.spdx ================================================ SPDXVersion: SPDX-2.2 DataLicense: CC0-1.0 SPDXID: SPDXRef-DOCUMENT DocumentName: FreeRTOS-Kernel DocumentNamespace: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/v10.5.1/sbom.spdx Creator: Amazon Web Services Created: 2022-11-15T20:10:07Z CreatorComment: NOASSERTION DocumentComment: NOASSERTION PackageName: FreeRTOS-Kernel SPDXID: SPDXRef-Package-FreeRTOS-Kernel PackageVersion: v10.5.1 PackageDownloadLocation: https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/v10.5.1 PackageLicenseConcluded: MIT FilesAnalyzed: True PackageVerificationCode: 96e4888a8478768c165c6c3e8093b6ad74e7aa97 PackageCopyrightText: NOASSERTION PackageSummary: NOASSERTION PackageDescription: FreeRTOS Kernel. FileName: ./stream_buffer.c SPDXID: SPDXRef-File-stream_buffer.c FileChecksum: SHA1: 1c2baa1e757130210c05d59a7e07ac8ab9552018 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./croutine.c SPDXID: SPDXRef-File-croutine.c FileChecksum: SHA1: 803043ff6cc8b5d893963fe448589ef42cdacb14 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./event_groups.c SPDXID: SPDXRef-File-event_groups.c FileChecksum: SHA1: c0c7ecca4606f5985305abd2a2b6332f2e84607b LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./list.c SPDXID: SPDXRef-File-list.c FileChecksum: SHA1: 171e33e47d98bd69b41c2d96d6940be279dae1e1 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./queue.c SPDXID: SPDXRef-File-queue.c FileChecksum: SHA1: 592dc3d7b6341db514978706e74cd0c2948a7bb0 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./tasks.c SPDXID: SPDXRef-File-tasks.c FileChecksum: SHA1: c32e962fcc28232c55b19a2286f48beb73a42a95 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./timers.c SPDXID: SPDXRef-File-timers.c FileChecksum: SHA1: 5709c8fa637a1a7af9094d273e7895f69123d054 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/CCS/MSP430X/port.c SPDXID: SPDXRef-File-portable-CCS-MSP430X-port.c FileChecksum: SHA1: 5079359be02915999512b97cfdd0466d1206da0c LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/CCS/ARM_CM4F/port.c SPDXID: SPDXRef-File-portable-CCS-ARM_CM4F-port.c FileChecksum: SHA1: 6acf3c7164f96612e3ee25189446b9444b82b73d LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/CCS/ARM_CM3/port.c SPDXID: SPDXRef-File-portable-CCS-ARM_CM3-port.c FileChecksum: SHA1: a26e6f70312a7947d0c00452ed0620fc97557872 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/CCS/ARM_Cortex-R4/port.c SPDXID: SPDXRef-File-portable-CCS-ARM_Cortex-R4-port.c FileChecksum: SHA1: 6bb3269d1908d19449fb06981b51877123f63a5c LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/MikroC/ARM_CM4F/port.c SPDXID: SPDXRef-File-portable-MikroC-ARM_CM4F-port.c FileChecksum: SHA1: d486325d1f761bb70cfa29d1a483911d2e988575 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/BCC/16BitDOS/PC/port.c SPDXID: SPDXRef-File-portable-BCC-16BitDOS-PC-port.c FileChecksum: SHA1: 68dc85a243ef9cdc6ac11359f136386787b0cbd6 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/BCC/16BitDOS/common/portcomn.c SPDXID: SPDXRef-File-portable-BCC-16BitDOS-common-portcomn.c FileChecksum: SHA1: 9ce97d3e33238cab16faa1ca9880736db727223c LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/BCC/16BitDOS/Flsh186/port.c SPDXID: SPDXRef-File-portable-BCC-16BitDOS-Flsh186-port.c FileChecksum: SHA1: 35b8e43c195af5f4757ef39b549971a7e2215f12 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/Rowley/MSP430F449/port.c SPDXID: SPDXRef-File-portable-Rowley-MSP430F449-port.c FileChecksum: SHA1: 8105f0e88d952d925140f7050554254d52d87bdf LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/SDCC/Cygnal/port.c SPDXID: SPDXRef-File-portable-SDCC-Cygnal-port.c FileChecksum: SHA1: a297d40f8ef95f6d78c5b64a1e00c36b777c6937 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/RVDS/ARM_CM4_MPU/port.c SPDXID: SPDXRef-File-portable-RVDS-ARM_CM4_MPU-port.c FileChecksum: SHA1: 08344265c5e61d1b2ae7eb30a1d35d62ef79a274 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/RVDS/ARM7_LPC21xx/port.c SPDXID: SPDXRef-File-portable-RVDS-ARM7_LPC21xx-port.c FileChecksum: SHA1: ce442b6f66a3d869326dca2005bd80f66326600b LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/RVDS/ARM_CM7/r0p1/port.c SPDXID: SPDXRef-File-portable-RVDS-ARM_CM7-r0p1-port.c FileChecksum: SHA1: 7bcfb74d36ec1ea00ea3f9b2535c635da6933af1 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/RVDS/ARM_CM4F/port.c SPDXID: SPDXRef-File-portable-RVDS-ARM_CM4F-port.c FileChecksum: SHA1: 9e86fdeb88ec953c791938c22b505f3f15db979c LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/RVDS/ARM_CA9/port.c SPDXID: SPDXRef-File-portable-RVDS-ARM_CA9-port.c FileChecksum: SHA1: 5fd59e8f1451038843b5c53131ad8864f3b2da0e LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/RVDS/ARM_CM3/port.c SPDXID: SPDXRef-File-portable-RVDS-ARM_CM3-port.c FileChecksum: SHA1: 1dd525bf973639aee2e527bd275307b2f05a0691 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/RVDS/ARM_CM0/port.c SPDXID: SPDXRef-File-portable-RVDS-ARM_CM0-port.c FileChecksum: SHA1: 632b983eb081008e1457dddcf87648a37ea4005f LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/Paradigm/Tern_EE/large_untested/port.c SPDXID: SPDXRef-File-portable-Paradigm-Tern_EE-large_untested-port.c FileChecksum: SHA1: 0a20e0468a5858f5ba539d6d7657b9334780c64e LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/Paradigm/Tern_EE/small/port.c SPDXID: SPDXRef-File-portable-Paradigm-Tern_EE-small-port.c FileChecksum: SHA1: a77fe59c250015bb429431d5bc3c1ffb44499f0e LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM4_MPU/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM4_MPU-port.c FileChecksum: SHA1: 5622de1720c3516069bc636370a7d8e073533df8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/RL78/port.c SPDXID: SPDXRef-File-portable-GCC-RL78-port.c FileChecksum: SHA1: 65e8c385787853909d4ba9dae183ace2de959161 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/IA32_flat/port.c SPDXID: SPDXRef-File-portable-GCC-IA32_flat-port.c FileChecksum: SHA1: f5d0b9df9f6688bf3c145d102adf48aa1a692e93 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/NiosII/port.c SPDXID: SPDXRef-File-portable-GCC-NiosII-port.c FileChecksum: SHA1: c23194fccbdeed397df8f1018828c14a549d1e9e LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM7_LPC23xx/portISR.c SPDXID: SPDXRef-File-portable-GCC-ARM7_LPC23xx-portISR.c FileChecksum: SHA1: 7e7030c594c8ee5adc53438bd4179002e5703236 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM7_LPC23xx/port.c SPDXID: SPDXRef-File-portable-GCC-ARM7_LPC23xx-port.c FileChecksum: SHA1: 8479e66a9770b283c305fdbc78529869b612baa2 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM7/r0p1/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM7-r0p1-port.c FileChecksum: SHA1: 5553768cde1cf30e25d09c8162cb4a677df11779 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/MSP430F449/port.c SPDXID: SPDXRef-File-portable-GCC-MSP430F449-port.c FileChecksum: SHA1: 9696a0bf2621dc877561bcf63131d7d535379437 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM7_LPC2000/portISR.c SPDXID: SPDXRef-File-portable-GCC-ARM7_LPC2000-portISR.c FileChecksum: SHA1: f5258ff45edce2a18d1b51d4687a8d0690986b82 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM7_LPC2000/port.c SPDXID: SPDXRef-File-portable-GCC-ARM7_LPC2000-port.c FileChecksum: SHA1: 1f1bb8ed90f0bf1cc73d6d89f49e0ddf55149e95 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CRx_No_GIC/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CRx_No_GIC-port.c FileChecksum: SHA1: c75a366b6dbaf32f068abd15acb86b9ee9d66c4f LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/MicroBlazeV8/port.c SPDXID: SPDXRef-File-portable-GCC-MicroBlazeV8-port.c FileChecksum: SHA1: 9ebcac457d4378eb0c800d0d70693eb11703fb40 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/MicroBlazeV8/port_exceptions.c SPDXID: SPDXRef-File-portable-GCC-MicroBlazeV8-port_exceptions.c FileChecksum: SHA1: 6ddd34b4a6ed92717e3bd0bed2bebf318fa71f44 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/MicroBlaze/port.c SPDXID: SPDXRef-File-portable-GCC-MicroBlaze-port.c FileChecksum: SHA1: a7ecb0f974b6cffb683ea00e7b352c909f870477 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ColdFire_V2/port.c SPDXID: SPDXRef-File-portable-GCC-ColdFire_V2-port.c FileChecksum: SHA1: 932d76f4aef15e2e4a558da32481061b3da1d82c LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CA53_64_BIT/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CA53_64_BIT-port.c FileChecksum: SHA1: 3e878e86aef525cedfc311b9a3cbbc2c7142bb30 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM55_NTZ-non_secure-portasm.c FileChecksum: SHA1: 249729a046c0fe1fc8dd3397f443c4c9979499b9 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM55_NTZ/non_secure/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM55_NTZ-non_secure-port.c FileChecksum: SHA1: 7232f62ebf97fdae174d06b2471f352975c10fa8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM3_MPU/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM3_MPU-port.c FileChecksum: SHA1: da7419edd8b969db2a3263cf576f2917ee629a58 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CR5/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CR5-port.c FileChecksum: SHA1: 361da1a5df63c05e9601d52dbaa6003eb3f38dc5 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/AVR32_UC3/port.c SPDXID: SPDXRef-File-portable-GCC-AVR32_UC3-port.c FileChecksum: SHA1: 4464b3b5081ef9adb39fb9ad26f5d6dd9c05ad84 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/RX200/port.c SPDXID: SPDXRef-File-portable-GCC-RX200-port.c FileChecksum: SHA1: 4e5358ee871244a2e00e06e546f0e1dfa9936d6d LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/STR75x/portISR.c SPDXID: SPDXRef-File-portable-GCC-STR75x-portISR.c FileChecksum: SHA1: dbe50473ddeb32c9ba7effa0c3ad5e66bc8192ed LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/STR75x/port.c SPDXID: SPDXRef-File-portable-GCC-STR75x-port.c FileChecksum: SHA1: 9ba5853c4865e7067fddedb1f54a5b1777e9308a LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM7_AT91FR40008/portISR.c SPDXID: SPDXRef-File-portable-GCC-ARM7_AT91FR40008-portISR.c FileChecksum: SHA1: 189a0b302ba2562b823c28763bc7aefe8687217f LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM7_AT91FR40008/port.c SPDXID: SPDXRef-File-portable-GCC-ARM7_AT91FR40008-port.c FileChecksum: SHA1: 24b38b808a31dcc5641d57c2365975b1e7328bb8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM33/non_secure/portasm.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM33-non_secure-portasm.c FileChecksum: SHA1: 6304a240212afc5aa5c44ef0bc4bd3da50f55e9b LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM33/non_secure/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM33-non_secure-port.c FileChecksum: SHA1: 7232f62ebf97fdae174d06b2471f352975c10fa8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM33/secure/secure_context_port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM33-secure-secure_context_port.c FileChecksum: SHA1: d9e90b3025d88a9defa5dbdc83cbcd3b86bc3ce4 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM33/secure/secure_heap.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM33-secure-secure_heap.c FileChecksum: SHA1: c803853724f8df8fca2a6c3520bc4ac83ffa9cc1 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM33/secure/secure_context.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM33-secure-secure_context.c FileChecksum: SHA1: 3b18903a3259d37caeede1d293d27c0701fcb33d LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM33/secure/secure_init.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM33-secure-secure_init.c FileChecksum: SHA1: 01d9390f6968031088f52ff615c165fa8e7e78b6 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM4F/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM4F-port.c FileChecksum: SHA1: 71d433f0bfef365a86e23e415ec563435a04e757 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM33_NTZ-non_secure-portasm.c FileChecksum: SHA1: cb80a39285b76c42e97c9503b3018186b4c1a59d LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM33_NTZ/non_secure/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM33_NTZ-non_secure-port.c FileChecksum: SHA1: 7232f62ebf97fdae174d06b2471f352975c10fa8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/PPC405_Xilinx/port.c SPDXID: SPDXRef-File-portable-GCC-PPC405_Xilinx-port.c FileChecksum: SHA1: 478ba8d7b3ba53d0fe3367094f18d159ec21b806 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/RISC-V/port.c SPDXID: SPDXRef-File-portable-GCC-RISC-V-port.c FileChecksum: SHA1: 129809b6812071585f3bd53888c447953879dd6f LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/RX100/port.c SPDXID: SPDXRef-File-portable-GCC-RX100-port.c FileChecksum: SHA1: 02e373ddc7cb1b4f56aaf861d648c6da72e584d3 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/CORTUS_APS3/port.c SPDXID: SPDXRef-File-portable-GCC-CORTUS_APS3-port.c FileChecksum: SHA1: 747e7e9d4f1c3c9830a0ef80a3780ccb923544be LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/H8S2329/port.c SPDXID: SPDXRef-File-portable-GCC-H8S2329-port.c FileChecksum: SHA1: 181bccd24e13159d6dee345119b4b1c3183ee4ef LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/HCS12/port.c SPDXID: SPDXRef-File-portable-GCC-HCS12-port.c FileChecksum: SHA1: 546bc475d0b0f79c1431910313b2ff534af85762 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM85_NTZ-non_secure-portasm.c FileChecksum: SHA1: cb80a39285b76c42e97c9503b3018186b4c1a59d LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM85_NTZ/non_secure/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM85_NTZ-non_secure-port.c FileChecksum: SHA1: 7232f62ebf97fdae174d06b2471f352975c10fa8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/RX600/port.c SPDXID: SPDXRef-File-portable-GCC-RX600-port.c FileChecksum: SHA1: fc5cbc2e2d53e32e01670dae4f5a2461932d6ce4 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/PPC440_Xilinx/port.c SPDXID: SPDXRef-File-portable-GCC-PPC440_Xilinx-port.c FileChecksum: SHA1: b9a24e917dc2ee679e4881fe4361c188ef58cb2c LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ATMega323/port.c SPDXID: SPDXRef-File-portable-GCC-ATMega323-port.c FileChecksum: SHA1: 9429770b499b8b243eb2bd347ac958f9b484c82e LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CA9/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CA9-port.c FileChecksum: SHA1: d19ffa018e122844d3f73aa0e941e5955b824c90 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/MicroBlazeV9/port.c SPDXID: SPDXRef-File-portable-GCC-MicroBlazeV9-port.c FileChecksum: SHA1: 01eaffe9ef3c1ea0f71899f62614d6a41c78d109 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/MicroBlazeV9/port_exceptions.c SPDXID: SPDXRef-File-portable-GCC-MicroBlazeV9-port_exceptions.c FileChecksum: SHA1: 6ddd34b4a6ed92717e3bd0bed2bebf318fa71f44 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM7_AT91SAM7S/lib_AT91SAM7X256.c SPDXID: SPDXRef-File-portable-GCC-ARM7_AT91SAM7S-lib_AT91SAM7X256.c FileChecksum: SHA1: 19a5b91dc5a9e1ed3e5e38cece6315a6494610e9 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM7_AT91SAM7S/portISR.c SPDXID: SPDXRef-File-portable-GCC-ARM7_AT91SAM7S-portISR.c FileChecksum: SHA1: 9d183db30d2b904c015784de3c3e4792d9375c38 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM7_AT91SAM7S/port.c SPDXID: SPDXRef-File-portable-GCC-ARM7_AT91SAM7S-port.c FileChecksum: SHA1: fba8714b48bd6a37bddd180a8527c1ae107ab9d1 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/TriCore_1782/porttrap.c SPDXID: SPDXRef-File-portable-GCC-TriCore_1782-porttrap.c FileChecksum: SHA1: 40a6505eddb3c75ed15a12762eb1b80d3bcc9727 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/TriCore_1782/port.c SPDXID: SPDXRef-File-portable-GCC-TriCore_1782-port.c FileChecksum: SHA1: fe6d901cfcbc5e421aaf2ce07af586334d7a1493 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM23/non_secure/portasm.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM23-non_secure-portasm.c FileChecksum: SHA1: 711c1344bb9577c56ccc4a708a631963d38217b5 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM23/non_secure/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM23-non_secure-port.c FileChecksum: SHA1: 7232f62ebf97fdae174d06b2471f352975c10fa8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM23/secure/secure_context_port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM23-secure-secure_context_port.c FileChecksum: SHA1: 36b3e28d4a98d49d7e36e11808a6c4cac77a51bb LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM23/secure/secure_heap.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM23-secure-secure_heap.c FileChecksum: SHA1: c803853724f8df8fca2a6c3520bc4ac83ffa9cc1 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM23/secure/secure_context.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM23-secure-secure_context.c FileChecksum: SHA1: 3b18903a3259d37caeede1d293d27c0701fcb33d LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM23/secure/secure_init.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM23-secure-secure_init.c FileChecksum: SHA1: 01d9390f6968031088f52ff615c165fa8e7e78b6 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM85/non_secure/portasm.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM85-non_secure-portasm.c FileChecksum: SHA1: 6304a240212afc5aa5c44ef0bc4bd3da50f55e9b LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM85/non_secure/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM85-non_secure-port.c FileChecksum: SHA1: 7232f62ebf97fdae174d06b2471f352975c10fa8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM85/secure/secure_context_port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM85-secure-secure_context_port.c FileChecksum: SHA1: d9e90b3025d88a9defa5dbdc83cbcd3b86bc3ce4 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM85/secure/secure_heap.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM85-secure-secure_heap.c FileChecksum: SHA1: c803853724f8df8fca2a6c3520bc4ac83ffa9cc1 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM85/secure/secure_context.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM85-secure-secure_context.c FileChecksum: SHA1: 3b18903a3259d37caeede1d293d27c0701fcb33d LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM85/secure/secure_init.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM85-secure-secure_init.c FileChecksum: SHA1: 01d9390f6968031088f52ff615c165fa8e7e78b6 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/RX600v2/port.c SPDXID: SPDXRef-File-portable-GCC-RX600v2-port.c FileChecksum: SHA1: 6aab3ba8300af09fbddd957b1c1a5de0d53769be LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM3/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM3-port.c FileChecksum: SHA1: 8c5dfff3e4766a347d9cd2a893a2471c2c7e0cc0 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/RX700v3_DPFPU/port.c SPDXID: SPDXRef-File-portable-GCC-RX700v3_DPFPU-port.c FileChecksum: SHA1: 3a8da1877c46b1be823f39951c833b25813c431f LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM55/non_secure/portasm.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM55-non_secure-portasm.c FileChecksum: SHA1: 57d0b9f14d59d28ed4d8ade666027477275c9528 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM55/non_secure/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM55-non_secure-port.c FileChecksum: SHA1: 7232f62ebf97fdae174d06b2471f352975c10fa8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM55/secure/secure_context_port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM55-secure-secure_context_port.c FileChecksum: SHA1: 64adb6bc89a3d0460649f8ed6ce92bfe96899929 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM55/secure/secure_heap.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM55-secure-secure_heap.c FileChecksum: SHA1: 22131716159658eb5b7980fbb4fbf6cc42506401 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM55/secure/secure_context.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM55-secure-secure_context.c FileChecksum: SHA1: 63fdeebd74ef8654c61d0d8f1497f744b01206b1 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM55/secure/secure_init.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM55-secure-secure_init.c FileChecksum: SHA1: b7f2d8f69ca99be60568173cc844829f8cf80e97 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CA53_64_BIT_SRE/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CA53_64_BIT_SRE-port.c FileChecksum: SHA1: af55c9568b7e180ed2a3295ab0a8c35cb376b43b LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM23_NTZ/non_secure/portasm.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM23_NTZ-non_secure-portasm.c FileChecksum: SHA1: eb7744902f32d79cd58476d03b846aa25b154895 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM23_NTZ/non_secure/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM23_NTZ-non_secure-port.c FileChecksum: SHA1: 7232f62ebf97fdae174d06b2471f352975c10fa8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/GCC/ARM_CM0/port.c SPDXID: SPDXRef-File-portable-GCC-ARM_CM0-port.c FileChecksum: SHA1: 4b98a3f5e7cdb6d4969475d6415631e9b3dd9f54 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/Softune/MB96340/port.c SPDXID: SPDXRef-File-portable-Softune-MB96340-port.c FileChecksum: SHA1: 7fcb818f839785ad0939a8ff19d180f523d9d899 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/Softune/MB96340/__STD_LIB_sbrk.c SPDXID: SPDXRef-File-portable-Softune-MB96340-__STD_LIB_sbrk.c FileChecksum: SHA1: 10f8f82190ade6d7986582215cb7fc52d8f137ec LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/Softune/MB91460/port.c SPDXID: SPDXRef-File-portable-Softune-MB91460-port.c FileChecksum: SHA1: 4e6eedebdf6057a3b5ecc6ccf974d3b71b0c93bf LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/Softune/MB91460/__STD_LIB_sbrk.c SPDXID: SPDXRef-File-portable-Softune-MB91460-__STD_LIB_sbrk.c FileChecksum: SHA1: 10f8f82190ade6d7986582215cb7fc52d8f137ec LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ARMv8M/non_secure/port.c SPDXID: SPDXRef-File-portable-ARMv8M-non_secure-port.c FileChecksum: SHA1: 7232f62ebf97fdae174d06b2471f352975c10fa8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c SPDXID: SPDXRef-File-portable-ARMv8M-non_secure-portable-GCC-ARM_CM33-portasm.c FileChecksum: SHA1: 6304a240212afc5aa5c44ef0bc4bd3da50f55e9b LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c SPDXID: SPDXRef-File-portable-ARMv8M-non_secure-portable-GCC-ARM_CM33_NTZ-portasm.c FileChecksum: SHA1: cb80a39285b76c42e97c9503b3018186b4c1a59d LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c SPDXID: SPDXRef-File-portable-ARMv8M-non_secure-portable-GCC-ARM_CM23-portasm.c FileChecksum: SHA1: 711c1344bb9577c56ccc4a708a631963d38217b5 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portasm.c SPDXID: SPDXRef-File-portable-ARMv8M-non_secure-portable-GCC-ARM_CM23_NTZ-portasm.c FileChecksum: SHA1: eb7744902f32d79cd58476d03b846aa25b154895 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ARMv8M/secure/heap/secure_heap.c SPDXID: SPDXRef-File-portable-ARMv8M-secure-heap-secure_heap.c FileChecksum: SHA1: c803853724f8df8fca2a6c3520bc4ac83ffa9cc1 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ARMv8M/secure/context/secure_context.c SPDXID: SPDXRef-File-portable-ARMv8M-secure-context-secure_context.c FileChecksum: SHA1: 3b18903a3259d37caeede1d293d27c0701fcb33d LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ARMv8M/secure/context/portable/GCC/ARM_CM33/secure_context_port.c SPDXID: SPDXRef-File-portable-ARMv8M-secure-context-portable-GCC-ARM_CM33-secure_context_port.c FileChecksum: SHA1: d9e90b3025d88a9defa5dbdc83cbcd3b86bc3ce4 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ARMv8M/secure/context/portable/GCC/ARM_CM23/secure_context_port.c SPDXID: SPDXRef-File-portable-ARMv8M-secure-context-portable-GCC-ARM_CM23-secure_context_port.c FileChecksum: SHA1: 36b3e28d4a98d49d7e36e11808a6c4cac77a51bb LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ARMv8M/secure/init/secure_init.c SPDXID: SPDXRef-File-portable-ARMv8M-secure-init-secure_init.c FileChecksum: SHA1: 01d9390f6968031088f52ff615c165fa8e7e78b6 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/Renesas/SH2A_FPU/port.c SPDXID: SPDXRef-File-portable-Renesas-SH2A_FPU-port.c FileChecksum: SHA1: 5d7a1294a1538c79222b3ddeca9d015ecd57b76b LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/Renesas/RX200/port.c SPDXID: SPDXRef-File-portable-Renesas-RX200-port.c FileChecksum: SHA1: 241c5e8350799f4539de632e449807ebec550060 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/Renesas/RX100/port.c SPDXID: SPDXRef-File-portable-Renesas-RX100-port.c FileChecksum: SHA1: 0ee930bd04ed137571337003b278867478316d17 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/Renesas/RX600/port.c SPDXID: SPDXRef-File-portable-Renesas-RX600-port.c FileChecksum: SHA1: cb819b866379b2e8dd5efb5d672431b34bbd7912 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/Renesas/RX600v2/port.c SPDXID: SPDXRef-File-portable-Renesas-RX600v2-port.c FileChecksum: SHA1: e75835734a6e50caca7b9bd158a4ffdc029ecb66 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/Renesas/RX700v3_DPFPU/port.c SPDXID: SPDXRef-File-portable-Renesas-RX700v3_DPFPU-port.c FileChecksum: SHA1: c119de3d323938b05ccde47896e0a43efeff09b4 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/MPLAB/PIC18F/port.c SPDXID: SPDXRef-File-portable-MPLAB-PIC18F-port.c FileChecksum: SHA1: 4df82e21e6eb1624358bb52fa5018b386bd12a1c LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/MPLAB/PIC32MEC14xx/port.c SPDXID: SPDXRef-File-portable-MPLAB-PIC32MEC14xx-port.c FileChecksum: SHA1: b5d1e2de6ba94d5cc934185debc9768567d45598 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/MPLAB/PIC32MX/port.c SPDXID: SPDXRef-File-portable-MPLAB-PIC32MX-port.c FileChecksum: SHA1: 1de50dd19ae325da0c8ec70bdfa9eec92d8cfa0d LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/MPLAB/PIC32MZ/port.c SPDXID: SPDXRef-File-portable-MPLAB-PIC32MZ-port.c FileChecksum: SHA1: f0b399058bec945374ffe75a119e9c4beb8baa1e LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/MPLAB/PIC24_dsPIC/port.c SPDXID: SPDXRef-File-portable-MPLAB-PIC24_dsPIC-port.c FileChecksum: SHA1: fa26fdd93ada4b92fa8f02dba77be2ff149eb15d LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/CodeWarrior/ColdFire_V2/port.c SPDXID: SPDXRef-File-portable-CodeWarrior-ColdFire_V2-port.c FileChecksum: SHA1: 7afcc073470e64ae5624ccce6a07235f687791f1 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/CodeWarrior/HCS12/port.c SPDXID: SPDXRef-File-portable-CodeWarrior-HCS12-port.c FileChecksum: SHA1: e877ad2139c9a315381e3bdfd19708a88539b0b3 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/CodeWarrior/ColdFire_V1/port.c SPDXID: SPDXRef-File-portable-CodeWarrior-ColdFire_V1-port.c FileChecksum: SHA1: 3b71e7d8a7d044de0b25d1e36214414bb8be3b39 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/MemMang/heap_4.c SPDXID: SPDXRef-File-portable-MemMang-heap_4.c FileChecksum: SHA1: a452f279d3f91d1e601a0e4a4221008fd422c556 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/MemMang/heap_5.c SPDXID: SPDXRef-File-portable-MemMang-heap_5.c FileChecksum: SHA1: 540a3bbe77e3e313d28b3a32d9342f7fb6e6795b LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/MemMang/heap_2.c SPDXID: SPDXRef-File-portable-MemMang-heap_2.c FileChecksum: SHA1: 8eba4818731d400281f9970485d684fca9fcd4b8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/MemMang/heap_3.c SPDXID: SPDXRef-File-portable-MemMang-heap_3.c FileChecksum: SHA1: 6409c5f00557bdc65c628440f706383bb1e9415b LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/MemMang/heap_1.c SPDXID: SPDXRef-File-portable-MemMang-heap_1.c FileChecksum: SHA1: 3db10e6ac9d56efcdd9f7e86bbbf7974941f413c LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/GCC/ARC_v1/arc_freertos_exceptions.c SPDXID: SPDXRef-File-portable-ThirdParty-GCC-ARC_v1-arc_freertos_exceptions.c FileChecksum: SHA1: 39ad9008f7017ea75ba984a2867d31afaf836d10 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/GCC/ARC_v1/port.c SPDXID: SPDXRef-File-portable-ThirdParty-GCC-ARC_v1-port.c FileChecksum: SHA1: a25919da8c7506a32c089112675e48277ca3fee4 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/GCC/ARC_EM_HS/arc_freertos_exceptions.c SPDXID: SPDXRef-File-portable-ThirdParty-GCC-ARC_EM_HS-arc_freertos_exceptions.c FileChecksum: SHA1: 39ad9008f7017ea75ba984a2867d31afaf836d10 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/GCC/ARC_EM_HS/freertos_tls.c SPDXID: SPDXRef-File-portable-ThirdParty-GCC-ARC_EM_HS-freertos_tls.c FileChecksum: SHA1: 170c3aae182620ee388eb2ca00c65345186bf4e5 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/GCC/ARC_EM_HS/port.c SPDXID: SPDXRef-File-portable-ThirdParty-GCC-ARC_EM_HS-port.c FileChecksum: SHA1: 805cbb1d4a1c078df121567329019a9337329d7f LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/GCC/Posix/port.c SPDXID: SPDXRef-File-portable-ThirdParty-GCC-Posix-port.c FileChecksum: SHA1: 892e342fd230a2c6e7d3c5cc8e9346a00a38ab4f LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/GCC/Posix/utils/wait_for_event.c SPDXID: SPDXRef-File-portable-ThirdParty-GCC-Posix-utils-wait_for_event.c FileChecksum: SHA1: a46806f9b7316a4efaef388288a4613966c72fc4 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c SPDXID: SPDXRef-File-portable-ThirdParty-GCC-ARM_TFM-os_wrapper_freertos.c FileChecksum: SHA1: a1420f4f796a50fc3173a7a1600e7b1f43fbf809 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/GCC/RP2040/idle_task_static_memory.c SPDXID: SPDXRef-File-portable-ThirdParty-GCC-RP2040-idle_task_static_memory.c FileChecksum: SHA1: 99f20e3882c2630f8bbf56be338649a06a8347aa LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/GCC/RP2040/port.c SPDXID: SPDXRef-File-portable-ThirdParty-GCC-RP2040-port.c FileChecksum: SHA1: 2473956780bf9652ff18f63b79b1d26c9f3eb608 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/GCC/Xtensa_ESP32/FreeRTOS-openocd.c SPDXID: SPDXRef-File-portable-ThirdParty-GCC-Xtensa_ESP32-FreeRTOS-openocd.c FileChecksum: SHA1: edeb30d33792d57505b80799a88034c810d7ce0b LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/GCC/Xtensa_ESP32/port_common.c SPDXID: SPDXRef-File-portable-ThirdParty-GCC-Xtensa_ESP32-port_common.c FileChecksum: SHA1: 12af31796408503788ec51c48d526258b6bc413b LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/GCC/Xtensa_ESP32/xtensa_overlay_os_hook.c SPDXID: SPDXRef-File-portable-ThirdParty-GCC-Xtensa_ESP32-xtensa_overlay_os_hook.c FileChecksum: SHA1: f7bc6354e74d83ac2ee094652693c454397e9599 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/GCC/Xtensa_ESP32/xtensa_init.c SPDXID: SPDXRef-File-portable-ThirdParty-GCC-Xtensa_ESP32-xtensa_init.c FileChecksum: SHA1: 8e0fd89383eb408a6d3b2c3aa50e49f0ec3b442e LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/GCC/Xtensa_ESP32/port_systick.c SPDXID: SPDXRef-File-portable-ThirdParty-GCC-Xtensa_ESP32-port_systick.c FileChecksum: SHA1: b00142b18bfa91bdca90d876ebe03e4a8dac77e7 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/GCC/Xtensa_ESP32/port.c SPDXID: SPDXRef-File-portable-ThirdParty-GCC-Xtensa_ESP32-port.c FileChecksum: SHA1: 0f63ba2624dc440e52380e0ab830752990113a66 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/GCC/ATmega/port.c SPDXID: SPDXRef-File-portable-ThirdParty-GCC-ATmega-port.c FileChecksum: SHA1: 1ed1936055df89ebc12f76053b2e05e9b9eb6637 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/XCC/Xtensa/xtensa_overlay_os_hook.c SPDXID: SPDXRef-File-portable-ThirdParty-XCC-Xtensa-xtensa_overlay_os_hook.c FileChecksum: SHA1: 8f0b2a50380c6becd723c252ea77184cd7c619ec LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/XCC/Xtensa/xtensa_init.c SPDXID: SPDXRef-File-portable-ThirdParty-XCC-Xtensa-xtensa_init.c FileChecksum: SHA1: 3d3f167933e7667425de96a9a70443c8380edd6f LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/XCC/Xtensa/xtensa_intr.c SPDXID: SPDXRef-File-portable-ThirdParty-XCC-Xtensa-xtensa_intr.c FileChecksum: SHA1: 58190888bee2d7c656d4d8d1d2fe7f19d26a832e LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/XCC/Xtensa/port.c SPDXID: SPDXRef-File-portable-ThirdParty-XCC-Xtensa-port.c FileChecksum: SHA1: a58c46bf18fd642d752a253d0bdd43e7f42ecdb0 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/XCC/Xtensa/portclib.c SPDXID: SPDXRef-File-portable-ThirdParty-XCC-Xtensa-portclib.c FileChecksum: SHA1: 535f96d2764bbad5d013c2e60a49d67c48fa1b9e LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/ThirdParty/CDK/T-HEAD_CK802/port.c SPDXID: SPDXRef-File-portable-ThirdParty-CDK-T-HEAD_CK802-port.c FileChecksum: SHA1: 7f58981ec9cd97ae40bd50098f122133b96d8494 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/RL78/port.c SPDXID: SPDXRef-File-portable-IAR-RL78-port.c FileChecksum: SHA1: 4bf9be3234e1ac537c89efb0e013c3dcd1c022b5 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/MSP430X/port.c SPDXID: SPDXRef-File-portable-IAR-MSP430X-port.c FileChecksum: SHA1: a2854f1e542068d6a0dee5ef78d2bf1fb03dcbf5 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM7/r0p1/port.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM7-r0p1-port.c FileChecksum: SHA1: 131ec8dfd40e23d1b019c698d72d89e3b987967c LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CRx_No_GIC/port.c SPDXID: SPDXRef-File-portable-IAR-ARM_CRx_No_GIC-port.c FileChecksum: SHA1: cc15c2006d4d4fdd984c022a2cc232796697ee69 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/V850ES/port.c SPDXID: SPDXRef-File-portable-IAR-V850ES-port.c FileChecksum: SHA1: 5f38b24fdfb372b6f4c9dc709cd8cf6e0095ba7f LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM55_NTZ/non_secure/port.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM55_NTZ-non_secure-port.c FileChecksum: SHA1: 7232f62ebf97fdae174d06b2471f352975c10fa8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/AVR32_UC3/read.c SPDXID: SPDXRef-File-portable-IAR-AVR32_UC3-read.c FileChecksum: SHA1: 2e690795b10a32cec32f55dde960296c62d0f72a LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/AVR32_UC3/write.c SPDXID: SPDXRef-File-portable-IAR-AVR32_UC3-write.c FileChecksum: SHA1: 0e44f45e2f2fb5b46b769a9571d1ffb9780ddf13 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/AVR32_UC3/port.c SPDXID: SPDXRef-File-portable-IAR-AVR32_UC3-port.c FileChecksum: SHA1: 7b7c43fcfe227114d4d09cfda433670ea9561602 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/STR75x/port.c SPDXID: SPDXRef-File-portable-IAR-STR75x-port.c FileChecksum: SHA1: 305cbe5c84979974a6a6124115b7ddf373624fdd LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/78K0R/port.c SPDXID: SPDXRef-File-portable-IAR-78K0R-port.c FileChecksum: SHA1: 3d4f06e3c7eeb7c4f6c952d78e486c2141116f88 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/AVR_Mega0/port.c SPDXID: SPDXRef-File-portable-IAR-AVR_Mega0-port.c FileChecksum: SHA1: b223c11cc6b1cf6bddd6f6943925295cc5f5aa7f LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM33/non_secure/port.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM33-non_secure-port.c FileChecksum: SHA1: 7232f62ebf97fdae174d06b2471f352975c10fa8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM33/secure/secure_heap.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM33-secure-secure_heap.c FileChecksum: SHA1: c803853724f8df8fca2a6c3520bc4ac83ffa9cc1 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM33/secure/secure_context.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM33-secure-secure_context.c FileChecksum: SHA1: 3b18903a3259d37caeede1d293d27c0701fcb33d LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM33/secure/secure_init.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM33-secure-secure_init.c FileChecksum: SHA1: 01d9390f6968031088f52ff615c165fa8e7e78b6 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM4F/port.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM4F-port.c FileChecksum: SHA1: b9ec3095d50b4825686c3a3629ff22fafb84c4ba LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM33_NTZ/non_secure/port.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM33_NTZ-non_secure-port.c FileChecksum: SHA1: 7232f62ebf97fdae174d06b2471f352975c10fa8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/AtmelSAM9XE/port.c SPDXID: SPDXRef-File-portable-IAR-AtmelSAM9XE-port.c FileChecksum: SHA1: bdb25b559149aad7f2e5035fb4b12c70836f97a0 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/RISC-V/port.c SPDXID: SPDXRef-File-portable-IAR-RISC-V-port.c FileChecksum: SHA1: 5fe98520bdccddec759a1ddf74f066477bf09a37 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/AVR_AVRDx/port.c SPDXID: SPDXRef-File-portable-IAR-AVR_AVRDx-port.c FileChecksum: SHA1: d9d44c218c4bb0acf4c08a9243bedaac8d1cef71 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/MSP430/port.c SPDXID: SPDXRef-File-portable-IAR-MSP430-port.c FileChecksum: SHA1: 6812ef4c2c81568e602ba010133698c788e328e4 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/RX100/port.c SPDXID: SPDXRef-File-portable-IAR-RX100-port.c FileChecksum: SHA1: 27327ef2975dd1b2416e862515ae2f91062ca2a7 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM85_NTZ/non_secure/port.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM85_NTZ-non_secure-port.c FileChecksum: SHA1: 7232f62ebf97fdae174d06b2471f352975c10fa8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/RX600/port.c SPDXID: SPDXRef-File-portable-IAR-RX600-port.c FileChecksum: SHA1: 056369dded69a4ab5fb8d742b8159029bcce94ee LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ATMega323/port.c SPDXID: SPDXRef-File-portable-IAR-ATMega323-port.c FileChecksum: SHA1: 9e91a5680e94fedf407bdef7d65ef0bd7eabf799 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CA9/port.c SPDXID: SPDXRef-File-portable-IAR-ARM_CA9-port.c FileChecksum: SHA1: f6cf117194b079fd018bfc110139767bdf83863d LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/LPC2000/port.c SPDXID: SPDXRef-File-portable-IAR-LPC2000-port.c FileChecksum: SHA1: dd0ecf60f912ca493b23a0b11a050bc16aef4470 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/STR71x/port.c SPDXID: SPDXRef-File-portable-IAR-STR71x-port.c FileChecksum: SHA1: 8d1038c43c5d15a5e42097de07e85aa6ce2836ea LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/STR91x/port.c SPDXID: SPDXRef-File-portable-IAR-STR91x-port.c FileChecksum: SHA1: 83b791a7425091a6d57cbc6ad184dd2ccde67f7d LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM23/non_secure/port.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM23-non_secure-port.c FileChecksum: SHA1: 7232f62ebf97fdae174d06b2471f352975c10fa8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM23/secure/secure_heap.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM23-secure-secure_heap.c FileChecksum: SHA1: c803853724f8df8fca2a6c3520bc4ac83ffa9cc1 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM23/secure/secure_context.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM23-secure-secure_context.c FileChecksum: SHA1: 3b18903a3259d37caeede1d293d27c0701fcb33d LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM23/secure/secure_init.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM23-secure-secure_init.c FileChecksum: SHA1: 01d9390f6968031088f52ff615c165fa8e7e78b6 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM85/non_secure/port.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM85-non_secure-port.c FileChecksum: SHA1: 7232f62ebf97fdae174d06b2471f352975c10fa8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM85/secure/secure_heap.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM85-secure-secure_heap.c FileChecksum: SHA1: c803853724f8df8fca2a6c3520bc4ac83ffa9cc1 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM85/secure/secure_context.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM85-secure-secure_context.c FileChecksum: SHA1: 3b18903a3259d37caeede1d293d27c0701fcb33d LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM85/secure/secure_init.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM85-secure-secure_init.c FileChecksum: SHA1: 01d9390f6968031088f52ff615c165fa8e7e78b6 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/AtmelSAM7S64/port.c SPDXID: SPDXRef-File-portable-IAR-AtmelSAM7S64-port.c FileChecksum: SHA1: 914f1804113f6310f7c32568f2f8a29cdb4d6b1e LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM3/port.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM3-port.c FileChecksum: SHA1: b4fec57793f1c37717c45c89f40f0072826bde33 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/RX700v3_DPFPU/port.c SPDXID: SPDXRef-File-portable-IAR-RX700v3_DPFPU-port.c FileChecksum: SHA1: 2cb6881752a1fb40456d57794981f1ecb01e6bac LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM55/non_secure/port.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM55-non_secure-port.c FileChecksum: SHA1: 7232f62ebf97fdae174d06b2471f352975c10fa8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM55/secure/secure_heap.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM55-secure-secure_heap.c FileChecksum: SHA1: 22131716159658eb5b7980fbb4fbf6cc42506401 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM55/secure/secure_context.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM55-secure-secure_context.c FileChecksum: SHA1: 63fdeebd74ef8654c61d0d8f1497f744b01206b1 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM55/secure/secure_init.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM55-secure-secure_init.c FileChecksum: SHA1: b7f2d8f69ca99be60568173cc844829f8cf80e97 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CA5_No_GIC/port.c SPDXID: SPDXRef-File-portable-IAR-ARM_CA5_No_GIC-port.c FileChecksum: SHA1: 02c3d32075d1cdc269940644c42f4ae8cadc6e3b LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM4F_MPU/port.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM4F_MPU-port.c FileChecksum: SHA1: 9d5b22ffc3b5057ce7efa078234fbd6c0fa822c4 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/RXv2/port.c SPDXID: SPDXRef-File-portable-IAR-RXv2-port.c FileChecksum: SHA1: 8cb3e7d74c877997e65f38dfa026408ae56d1310 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM23_NTZ/non_secure/port.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM23_NTZ-non_secure-port.c FileChecksum: SHA1: 7232f62ebf97fdae174d06b2471f352975c10fa8 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/IAR/ARM_CM0/port.c SPDXID: SPDXRef-File-portable-IAR-ARM_CM0-port.c FileChecksum: SHA1: c7a94e88030646ba23683dd41f746f3513aec48b LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/Common/mpu_wrappers.c SPDXID: SPDXRef-File-portable-Common-mpu_wrappers.c FileChecksum: SHA1: cf1165968ba4bbeee12e38ca88161b96a2570fd1 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/Tasking/ARM_CM4F/port.c SPDXID: SPDXRef-File-portable-Tasking-ARM_CM4F-port.c FileChecksum: SHA1: 4e251295192027b1286d1a7fcd54cd5cebdc5bbc LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/oWatcom/16BitDOS/PC/port.c SPDXID: SPDXRef-File-portable-oWatcom-16BitDOS-PC-port.c FileChecksum: SHA1: 482f2ca2c10195a7dc0e5f2cbabddd11016295f1 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/oWatcom/16BitDOS/common/portcomn.c SPDXID: SPDXRef-File-portable-oWatcom-16BitDOS-common-portcomn.c FileChecksum: SHA1: 7ea2aeb5471e46f344883d38fd214b07bdbffb59 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/oWatcom/16BitDOS/Flsh186/port.c SPDXID: SPDXRef-File-portable-oWatcom-16BitDOS-Flsh186-port.c FileChecksum: SHA1: 52126b1ae32773c821d96dc8f9ddd55d67925dd6 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/WizC/PIC18/port.c SPDXID: SPDXRef-File-portable-WizC-PIC18-port.c FileChecksum: SHA1: c34cb4df1d9af422ab1137b837408f8edca37937 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/WizC/PIC18/Drivers/Tick/isrTick.c SPDXID: SPDXRef-File-portable-WizC-PIC18-Drivers-Tick-isrTick.c FileChecksum: SHA1: d209388fa9ab6fccf9a8cf9926aa06f7a0aef4a7 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/WizC/PIC18/Drivers/Tick/Tick.c SPDXID: SPDXRef-File-portable-WizC-PIC18-Drivers-Tick-Tick.c FileChecksum: SHA1: c8cb5a4c67115c0320ce85b1866144c89c8640a0 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION FileName: ./portable/MSVC-MingW/port.c SPDXID: SPDXRef-File-portable-MSVC-MingW-port.c FileChecksum: SHA1: bcf578edabca3bff3897cc1d7021f626a91129f9 LicenseConcluded: MIT FileCopyrightText: NOASSERTION FileComment: NOASSERTION ================================================ FILE: FreeRTOS-comparison/stream_buffer.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* FreeRTOS includes. */ #include "FreeRTOS.h" #include "task.h" #include "stream_buffer.h" #if ( configUSE_TASK_NOTIFICATIONS != 1 ) #error configUSE_TASK_NOTIFICATIONS must be set to 1 to build stream_buffer.c #endif #if ( INCLUDE_xTaskGetCurrentTaskHandle != 1 ) #error INCLUDE_xTaskGetCurrentTaskHandle must be set to 1 to build stream_buffer.c #endif /* Lint e961, e9021 and e750 are suppressed as a MISRA exception justified * because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined * for the header files above, but not in this file, in order to generate the * correct privileged Vs unprivileged linkage and placement. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ /* If the user has not provided application specific Rx notification macros, * or #defined the notification macros away, then provide default implementations * that uses task notifications. */ /*lint -save -e9026 Function like macros allowed and needed here so they can be overridden. */ #ifndef sbRECEIVE_COMPLETED #define sbRECEIVE_COMPLETED( pxStreamBuffer ) \ vTaskSuspendAll(); \ { \ if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ { \ ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToSend, \ ( uint32_t ) 0, \ eNoAction ); \ ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ } \ } \ ( void ) xTaskResumeAll(); #endif /* sbRECEIVE_COMPLETED */ /* If user has provided a per-instance receive complete callback, then * invoke the callback else use the receive complete macro which is provided by default for all instances. */ #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define prvRECEIVE_COMPLETED( pxStreamBuffer ) \ { \ if( ( pxStreamBuffer )->pxReceiveCompletedCallback != NULL ) \ { \ ( pxStreamBuffer )->pxReceiveCompletedCallback( ( pxStreamBuffer ), pdFALSE, NULL ); \ } \ else \ { \ sbRECEIVE_COMPLETED( ( pxStreamBuffer ) ); \ } \ } #else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ #define prvRECEIVE_COMPLETED( pxStreamBuffer ) sbRECEIVE_COMPLETED( ( pxStreamBuffer ) ) #endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ #ifndef sbRECEIVE_COMPLETED_FROM_ISR #define sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \ pxHigherPriorityTaskWoken ) \ { \ UBaseType_t uxSavedInterruptStatus; \ \ uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \ { \ if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ { \ ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, \ ( uint32_t ) 0, \ eNoAction, \ ( pxHigherPriorityTaskWoken ) ); \ ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ } \ } \ portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ } #endif /* sbRECEIVE_COMPLETED_FROM_ISR */ #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \ pxHigherPriorityTaskWoken ) \ { \ if( ( pxStreamBuffer )->pxReceiveCompletedCallback != NULL ) \ { \ ( pxStreamBuffer )->pxReceiveCompletedCallback( ( pxStreamBuffer ), pdTRUE, ( pxHigherPriorityTaskWoken ) ); \ } \ else \ { \ sbRECEIVE_COMPLETED_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ); \ } \ } #else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ #define prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ sbRECEIVE_COMPLETED_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ) #endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ /* If the user has not provided an application specific Tx notification macro, * or #defined the notification macro away, then provide a default * implementation that uses task notifications. */ #ifndef sbSEND_COMPLETED #define sbSEND_COMPLETED( pxStreamBuffer ) \ vTaskSuspendAll(); \ { \ if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ { \ ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToReceive, \ ( uint32_t ) 0, \ eNoAction ); \ ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ } \ } \ ( void ) xTaskResumeAll(); #endif /* sbSEND_COMPLETED */ /* If user has provided a per-instance send completed callback, then * invoke the callback else use the send complete macro which is provided by default for all instances. */ #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define prvSEND_COMPLETED( pxStreamBuffer ) \ { \ if( ( pxStreamBuffer )->pxSendCompletedCallback != NULL ) \ { \ pxStreamBuffer->pxSendCompletedCallback( ( pxStreamBuffer ), pdFALSE, NULL ); \ } \ else \ { \ sbSEND_COMPLETED( ( pxStreamBuffer ) ); \ } \ } #else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ #define prvSEND_COMPLETED( pxStreamBuffer ) sbSEND_COMPLETED( ( pxStreamBuffer ) ) #endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ #ifndef sbSEND_COMPLETE_FROM_ISR #define sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ { \ UBaseType_t uxSavedInterruptStatus; \ \ uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \ { \ if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ { \ ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, \ ( uint32_t ) 0, \ eNoAction, \ ( pxHigherPriorityTaskWoken ) ); \ ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ } \ } \ portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ } #endif /* sbSEND_COMPLETE_FROM_ISR */ #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ { \ if( ( pxStreamBuffer )->pxSendCompletedCallback != NULL ) \ { \ ( pxStreamBuffer )->pxSendCompletedCallback( ( pxStreamBuffer ), pdTRUE, ( pxHigherPriorityTaskWoken ) ); \ } \ else \ { \ sbSEND_COMPLETE_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ); \ } \ } #else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ #define prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ sbSEND_COMPLETE_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ) #endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ /*lint -restore (9026) */ /* The number of bytes used to hold the length of a message in the buffer. */ #define sbBYTES_TO_STORE_MESSAGE_LENGTH ( sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) ) /* Bits stored in the ucFlags field of the stream buffer. */ #define sbFLAGS_IS_MESSAGE_BUFFER ( ( uint8_t ) 1 ) /* Set if the stream buffer was created as a message buffer, in which case it holds discrete messages rather than a stream. */ #define sbFLAGS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 2 ) /* Set if the stream buffer was created using statically allocated memory. */ /*-----------------------------------------------------------*/ /* Structure that hold state information on the buffer. */ typedef struct StreamBufferDef_t /*lint !e9058 Style convention uses tag. */ { volatile size_t xTail; /* Index to the next item to read within the buffer. */ volatile size_t xHead; /* Index to the next item to write within the buffer. */ size_t xLength; /* The length of the buffer pointed to by pucBuffer. */ size_t xTriggerLevelBytes; /* The number of bytes that must be in the stream buffer before a task that is waiting for data is unblocked. */ volatile TaskHandle_t xTaskWaitingToReceive; /* Holds the handle of a task waiting for data, or NULL if no tasks are waiting. */ volatile TaskHandle_t xTaskWaitingToSend; /* Holds the handle of a task waiting to send data to a message buffer that is full. */ uint8_t * pucBuffer; /* Points to the buffer itself - that is - the RAM that stores the data passed through the buffer. */ uint8_t ucFlags; #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxStreamBufferNumber; /* Used for tracing purposes. */ #endif #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) StreamBufferCallbackFunction_t pxSendCompletedCallback; /* Optional callback called on send complete. sbSEND_COMPLETED is called if this is NULL. */ StreamBufferCallbackFunction_t pxReceiveCompletedCallback; /* Optional callback called on receive complete. sbRECEIVE_COMPLETED is called if this is NULL. */ #endif } StreamBuffer_t; /* * The number of bytes available to be read from the buffer. */ static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) PRIVILEGED_FUNCTION; /* * Add xCount bytes from pucData into the pxStreamBuffer's data storage area. * This function does not update the buffer's xHead pointer, so multiple writes * may be chained together "atomically". This is useful for Message Buffers where * the length and data bytes are written in two separate chunks, and we don't want * the reader to see the buffer as having grown until after all data is copied over. * This function takes a custom xHead value to indicate where to write to (necessary * for chaining) and returns the the resulting xHead position. * To mark the write as complete, manually set the buffer's xHead field with the * returned xHead from this function. */ static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, const uint8_t * pucData, size_t xCount, size_t xHead ) PRIVILEGED_FUNCTION; /* * If the stream buffer is being used as a message buffer, then reads an entire * message out of the buffer. If the stream buffer is being used as a stream * buffer then read as many bytes as possible from the buffer. * prvReadBytesFromBuffer() is called to actually extract the bytes from the * buffer's data storage area. */ static size_t prvReadMessageFromBuffer( StreamBuffer_t * pxStreamBuffer, void * pvRxData, size_t xBufferLengthBytes, size_t xBytesAvailable ) PRIVILEGED_FUNCTION; /* * If the stream buffer is being used as a message buffer, then writes an entire * message to the buffer. If the stream buffer is being used as a stream * buffer then write as many bytes as possible to the buffer. * prvWriteBytestoBuffer() is called to actually send the bytes to the buffer's * data storage area. */ static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer, const void * pvTxData, size_t xDataLengthBytes, size_t xSpace, size_t xRequiredSpace ) PRIVILEGED_FUNCTION; /* * Copies xCount bytes from the pxStreamBuffer's data storage area to pucData. * This function does not update the buffer's xTail pointer, so multiple reads * may be chained together "atomically". This is useful for Message Buffers where * the length and data bytes are read in two separate chunks, and we don't want * the writer to see the buffer as having more free space until after all data is * copied over, especially if we have to abort the read due to insufficient receiving space. * This function takes a custom xTail value to indicate where to read from (necessary * for chaining) and returns the the resulting xTail position. * To mark the read as complete, manually set the buffer's xTail field with the * returned xTail from this function. */ static size_t prvReadBytesFromBuffer( StreamBuffer_t * pxStreamBuffer, uint8_t * pucData, size_t xCount, size_t xTail ) PRIVILEGED_FUNCTION; /* * Called by both pxStreamBufferCreate() and pxStreamBufferCreateStatic() to * initialise the members of the newly created stream buffer structure. */ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, uint8_t * const pucBuffer, size_t xBufferSizeBytes, size_t xTriggerLevelBytes, uint8_t ucFlags, StreamBufferCallbackFunction_t pxSendCompletedCallback, StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) { uint8_t * pucAllocatedMemory; uint8_t ucFlags; /* In case the stream buffer is going to be used as a message buffer * (that is, it will hold discrete messages with a little meta data that * says how big the next message is) check the buffer will be large enough * to hold at least one message. */ if( xIsMessageBuffer == pdTRUE ) { /* Is a message buffer but not statically allocated. */ ucFlags = sbFLAGS_IS_MESSAGE_BUFFER; configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH ); } else { /* Not a message buffer and not statically allocated. */ ucFlags = 0; configASSERT( xBufferSizeBytes > 0 ); } configASSERT( xTriggerLevelBytes <= xBufferSizeBytes ); /* A trigger level of 0 would cause a waiting task to unblock even when * the buffer was empty. */ if( xTriggerLevelBytes == ( size_t ) 0 ) { xTriggerLevelBytes = ( size_t ) 1; } /* A stream buffer requires a StreamBuffer_t structure and a buffer. * Both are allocated in a single call to pvPortMalloc(). The * StreamBuffer_t structure is placed at the start of the allocated memory * and the buffer follows immediately after. The requested size is * incremented so the free space is returned as the user would expect - * this is a quirk of the implementation that means otherwise the free * space would be reported as one byte smaller than would be logically * expected. */ if( xBufferSizeBytes < ( xBufferSizeBytes + 1 + sizeof( StreamBuffer_t ) ) ) { xBufferSizeBytes++; pucAllocatedMemory = ( uint8_t * ) pvPortMalloc( xBufferSizeBytes + sizeof( StreamBuffer_t ) ); /*lint !e9079 malloc() only returns void*. */ } else { pucAllocatedMemory = NULL; } if( pucAllocatedMemory != NULL ) { prvInitialiseNewStreamBuffer( ( StreamBuffer_t * ) pucAllocatedMemory, /* Structure at the start of the allocated memory. */ /*lint !e9087 Safe cast as allocated memory is aligned. */ /*lint !e826 Area is not too small and alignment is guaranteed provided malloc() behaves as expected and returns aligned buffer. */ pucAllocatedMemory + sizeof( StreamBuffer_t ), /* Storage area follows. */ /*lint !e9016 Indexing past structure valid for uint8_t pointer, also storage area has no alignment requirement. */ xBufferSizeBytes, xTriggerLevelBytes, ucFlags, pxSendCompletedCallback, pxReceiveCompletedCallback ); traceSTREAM_BUFFER_CREATE( ( ( StreamBuffer_t * ) pucAllocatedMemory ), xIsMessageBuffer ); } else { traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ); } return ( StreamBufferHandle_t ) pucAllocatedMemory; /*lint !e9087 !e826 Safe cast as allocated memory is aligned. */ } #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ /*-----------------------------------------------------------*/ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) { StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) pxStaticStreamBuffer; /*lint !e740 !e9087 Safe cast as StaticStreamBuffer_t is opaque Streambuffer_t. */ StreamBufferHandle_t xReturn; uint8_t ucFlags; configASSERT( pucStreamBufferStorageArea ); configASSERT( pxStaticStreamBuffer ); configASSERT( xTriggerLevelBytes <= xBufferSizeBytes ); /* A trigger level of 0 would cause a waiting task to unblock even when * the buffer was empty. */ if( xTriggerLevelBytes == ( size_t ) 0 ) { xTriggerLevelBytes = ( size_t ) 1; } if( xIsMessageBuffer != pdFALSE ) { /* Statically allocated message buffer. */ ucFlags = sbFLAGS_IS_MESSAGE_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED; } else { /* Statically allocated stream buffer. */ ucFlags = sbFLAGS_IS_STATICALLY_ALLOCATED; } /* In case the stream buffer is going to be used as a message buffer * (that is, it will hold discrete messages with a little meta data that * says how big the next message is) check the buffer will be large enough * to hold at least one message. */ configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH ); #if ( configASSERT_DEFINED == 1 ) { /* Sanity check that the size of the structure used to declare a * variable of type StaticStreamBuffer_t equals the size of the real * message buffer structure. */ volatile size_t xSize = sizeof( StaticStreamBuffer_t ); configASSERT( xSize == sizeof( StreamBuffer_t ) ); } /*lint !e529 xSize is referenced is configASSERT() is defined. */ #endif /* configASSERT_DEFINED */ if( ( pucStreamBufferStorageArea != NULL ) && ( pxStaticStreamBuffer != NULL ) ) { prvInitialiseNewStreamBuffer( pxStreamBuffer, pucStreamBufferStorageArea, xBufferSizeBytes, xTriggerLevelBytes, ucFlags, pxSendCompletedCallback, pxReceiveCompletedCallback ); /* Remember this was statically allocated in case it is ever deleted * again. */ pxStreamBuffer->ucFlags |= sbFLAGS_IS_STATICALLY_ALLOCATED; traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ); xReturn = ( StreamBufferHandle_t ) pxStaticStreamBuffer; /*lint !e9087 Data hiding requires cast to opaque type. */ } else { xReturn = NULL; traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ); } return xReturn; } #endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ /*-----------------------------------------------------------*/ void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) { StreamBuffer_t * pxStreamBuffer = xStreamBuffer; configASSERT( pxStreamBuffer ); traceSTREAM_BUFFER_DELETE( xStreamBuffer ); if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) pdFALSE ) { #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) { /* Both the structure and the buffer were allocated using a single call * to pvPortMalloc(), hence only one call to vPortFree() is required. */ vPortFree( ( void * ) pxStreamBuffer ); /*lint !e9087 Standard free() semantics require void *, plus pxStreamBuffer was allocated by pvPortMalloc(). */ } #else { /* Should not be possible to get here, ucFlags must be corrupt. * Force an assert. */ configASSERT( xStreamBuffer == ( StreamBufferHandle_t ) ~0 ); } #endif } else { /* The structure and buffer were not allocated dynamically and cannot be * freed - just scrub the structure so future use will assert. */ ( void ) memset( pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); } } /*-----------------------------------------------------------*/ BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) { StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; BaseType_t xReturn = pdFAIL; StreamBufferCallbackFunction_t pxSendCallback = NULL, pxReceiveCallback = NULL; #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxStreamBufferNumber; #endif configASSERT( pxStreamBuffer ); #if ( configUSE_TRACE_FACILITY == 1 ) { /* Store the stream buffer number so it can be restored after the * reset. */ uxStreamBufferNumber = pxStreamBuffer->uxStreamBufferNumber; } #endif /* Can only reset a message buffer if there are no tasks blocked on it. */ taskENTER_CRITICAL(); { if( ( pxStreamBuffer->xTaskWaitingToReceive == NULL ) && ( pxStreamBuffer->xTaskWaitingToSend == NULL ) ) { #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) { pxSendCallback = pxStreamBuffer->pxSendCompletedCallback; pxReceiveCallback = pxStreamBuffer->pxReceiveCompletedCallback; } #endif prvInitialiseNewStreamBuffer( pxStreamBuffer, pxStreamBuffer->pucBuffer, pxStreamBuffer->xLength, pxStreamBuffer->xTriggerLevelBytes, pxStreamBuffer->ucFlags, pxSendCallback, pxReceiveCallback ); #if ( configUSE_TRACE_FACILITY == 1 ) { pxStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber; } #endif traceSTREAM_BUFFER_RESET( xStreamBuffer ); xReturn = pdPASS; } } taskEXIT_CRITICAL(); return xReturn; } /*-----------------------------------------------------------*/ BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) { StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; BaseType_t xReturn; configASSERT( pxStreamBuffer ); /* It is not valid for the trigger level to be 0. */ if( xTriggerLevel == ( size_t ) 0 ) { xTriggerLevel = ( size_t ) 1; } /* The trigger level is the number of bytes that must be in the stream * buffer before a task that is waiting for data is unblocked. */ if( xTriggerLevel < pxStreamBuffer->xLength ) { pxStreamBuffer->xTriggerLevelBytes = xTriggerLevel; xReturn = pdPASS; } else { xReturn = pdFALSE; } return xReturn; } /*-----------------------------------------------------------*/ size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) { const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; size_t xSpace; size_t xOriginalTail; configASSERT( pxStreamBuffer ); /* The code below reads xTail and then xHead. This is safe if the stream * buffer is updated once between the two reads - but not if the stream buffer * is updated more than once between the two reads - hence the loop. */ do { xOriginalTail = pxStreamBuffer->xTail; xSpace = pxStreamBuffer->xLength + pxStreamBuffer->xTail; xSpace -= pxStreamBuffer->xHead; } while( xOriginalTail != pxStreamBuffer->xTail ); xSpace -= ( size_t ) 1; if( xSpace >= pxStreamBuffer->xLength ) { xSpace -= pxStreamBuffer->xLength; } else { mtCOVERAGE_TEST_MARKER(); } return xSpace; } /*-----------------------------------------------------------*/ size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) { const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; size_t xReturn; configASSERT( pxStreamBuffer ); xReturn = prvBytesInBuffer( pxStreamBuffer ); return xReturn; } /*-----------------------------------------------------------*/ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void * pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) { StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; size_t xReturn, xSpace = 0; size_t xRequiredSpace = xDataLengthBytes; TimeOut_t xTimeOut; size_t xMaxReportedSpace = 0; configASSERT( pvTxData ); configASSERT( pxStreamBuffer ); /* The maximum amount of space a stream buffer will ever report is its length * minus 1. */ xMaxReportedSpace = pxStreamBuffer->xLength - ( size_t ) 1; /* This send function is used to write to both message buffers and stream * buffers. If this is a message buffer then the space needed must be * increased by the amount of bytes needed to store the length of the * message. */ if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) { xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH; /* Overflow? */ configASSERT( xRequiredSpace > xDataLengthBytes ); /* If this is a message buffer then it must be possible to write the * whole message. */ if( xRequiredSpace > xMaxReportedSpace ) { /* The message would not fit even if the entire buffer was empty, * so don't wait for space. */ xTicksToWait = ( TickType_t ) 0; } else { mtCOVERAGE_TEST_MARKER(); } } else { /* If this is a stream buffer then it is acceptable to write only part * of the message to the buffer. Cap the length to the total length of * the buffer. */ if( xRequiredSpace > xMaxReportedSpace ) { xRequiredSpace = xMaxReportedSpace; } else { mtCOVERAGE_TEST_MARKER(); } } if( xTicksToWait != ( TickType_t ) 0 ) { vTaskSetTimeOutState( &xTimeOut ); do { /* Wait until the required number of bytes are free in the message * buffer. */ taskENTER_CRITICAL(); { xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer ); if( xSpace < xRequiredSpace ) { /* Clear notification state as going to wait for space. */ ( void ) xTaskNotifyStateClear( NULL ); /* Should only be one writer. */ configASSERT( pxStreamBuffer->xTaskWaitingToSend == NULL ); pxStreamBuffer->xTaskWaitingToSend = xTaskGetCurrentTaskHandle(); } else { taskEXIT_CRITICAL(); break; } } taskEXIT_CRITICAL(); traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ); ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait ); pxStreamBuffer->xTaskWaitingToSend = NULL; } while( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ); } else { mtCOVERAGE_TEST_MARKER(); } if( xSpace == ( size_t ) 0 ) { xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer ); } else { mtCOVERAGE_TEST_MARKER(); } xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace ); if( xReturn > ( size_t ) 0 ) { traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn ); /* Was a task waiting for the data? */ if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes ) { prvSEND_COMPLETED( pxStreamBuffer ); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ); } return xReturn; } /*-----------------------------------------------------------*/ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, const void * pvTxData, size_t xDataLengthBytes, BaseType_t * const pxHigherPriorityTaskWoken ) { StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; size_t xReturn, xSpace; size_t xRequiredSpace = xDataLengthBytes; configASSERT( pvTxData ); configASSERT( pxStreamBuffer ); /* This send function is used to write to both message buffers and stream * buffers. If this is a message buffer then the space needed must be * increased by the amount of bytes needed to store the length of the * message. */ if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) { xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH; } else { mtCOVERAGE_TEST_MARKER(); } xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer ); xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace ); if( xReturn > ( size_t ) 0 ) { /* Was a task waiting for the data? */ if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes ) { prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn ); return xReturn; } /*-----------------------------------------------------------*/ static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer, const void * pvTxData, size_t xDataLengthBytes, size_t xSpace, size_t xRequiredSpace ) { size_t xNextHead = pxStreamBuffer->xHead; configMESSAGE_BUFFER_LENGTH_TYPE xMessageLength; if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) { /* This is a message buffer, as opposed to a stream buffer. */ /* Convert xDataLengthBytes to the message length type. */ xMessageLength = ( configMESSAGE_BUFFER_LENGTH_TYPE ) xDataLengthBytes; /* Ensure the data length given fits within configMESSAGE_BUFFER_LENGTH_TYPE. */ configASSERT( ( size_t ) xMessageLength == xDataLengthBytes ); if( xSpace >= xRequiredSpace ) { /* There is enough space to write both the message length and the message * itself into the buffer. Start by writing the length of the data, the data * itself will be written later in this function. */ xNextHead = prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) &( xMessageLength ), sbBYTES_TO_STORE_MESSAGE_LENGTH, xNextHead ); } else { /* Not enough space, so do not write data to the buffer. */ xDataLengthBytes = 0; } } else { /* This is a stream buffer, as opposed to a message buffer, so writing a * stream of bytes rather than discrete messages. Plan to write as many * bytes as possible. */ xDataLengthBytes = configMIN( xDataLengthBytes, xSpace ); } if( xDataLengthBytes != ( size_t ) 0 ) { /* Write the data to the buffer. */ pxStreamBuffer->xHead = prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) pvTxData, xDataLengthBytes, xNextHead ); /*lint !e9079 Storage buffer is implemented as uint8_t for ease of sizing, alignment and access. */ } return xDataLengthBytes; } /*-----------------------------------------------------------*/ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void * pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) { StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength; configASSERT( pvRxData ); configASSERT( pxStreamBuffer ); /* This receive function is used by both message buffers, which store * discrete messages, and stream buffers, which store a continuous stream of * bytes. Discrete messages include an additional * sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the * message. */ if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) { xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH; } else { xBytesToStoreMessageLength = 0; } if( xTicksToWait != ( TickType_t ) 0 ) { /* Checking if there is data and clearing the notification state must be * performed atomically. */ taskENTER_CRITICAL(); { xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); /* If this function was invoked by a message buffer read then * xBytesToStoreMessageLength holds the number of bytes used to hold * the length of the next discrete message. If this function was * invoked by a stream buffer read then xBytesToStoreMessageLength will * be 0. */ if( xBytesAvailable <= xBytesToStoreMessageLength ) { /* Clear notification state as going to wait for data. */ ( void ) xTaskNotifyStateClear( NULL ); /* Should only be one reader. */ configASSERT( pxStreamBuffer->xTaskWaitingToReceive == NULL ); pxStreamBuffer->xTaskWaitingToReceive = xTaskGetCurrentTaskHandle(); } else { mtCOVERAGE_TEST_MARKER(); } } taskEXIT_CRITICAL(); if( xBytesAvailable <= xBytesToStoreMessageLength ) { /* Wait for data to be available. */ traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ); ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait ); pxStreamBuffer->xTaskWaitingToReceive = NULL; /* Recheck the data available after blocking. */ xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); } else { mtCOVERAGE_TEST_MARKER(); } } else { xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); } /* Whether receiving a discrete message (where xBytesToStoreMessageLength * holds the number of bytes used to store the message length) or a stream of * bytes (where xBytesToStoreMessageLength is zero), the number of bytes * available must be greater than xBytesToStoreMessageLength to be able to * read bytes from the buffer. */ if( xBytesAvailable > xBytesToStoreMessageLength ) { xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable ); /* Was a task waiting for space in the buffer? */ if( xReceivedLength != ( size_t ) 0 ) { traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ); prvRECEIVE_COMPLETED( xStreamBuffer ); } else { mtCOVERAGE_TEST_MARKER(); } } else { traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ); mtCOVERAGE_TEST_MARKER(); } return xReceivedLength; } /*-----------------------------------------------------------*/ size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) { StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; size_t xReturn, xBytesAvailable; configMESSAGE_BUFFER_LENGTH_TYPE xTempReturn; configASSERT( pxStreamBuffer ); /* Ensure the stream buffer is being used as a message buffer. */ if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) { xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); if( xBytesAvailable > sbBYTES_TO_STORE_MESSAGE_LENGTH ) { /* The number of bytes available is greater than the number of bytes * required to hold the length of the next message, so another message * is available. */ ( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempReturn, sbBYTES_TO_STORE_MESSAGE_LENGTH, pxStreamBuffer->xTail ); xReturn = ( size_t ) xTempReturn; } else { /* The minimum amount of bytes in a message buffer is * ( sbBYTES_TO_STORE_MESSAGE_LENGTH + 1 ), so if xBytesAvailable is * less than sbBYTES_TO_STORE_MESSAGE_LENGTH the only other valid * value is 0. */ configASSERT( xBytesAvailable == 0 ); xReturn = 0; } } else { xReturn = 0; } return xReturn; } /*-----------------------------------------------------------*/ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, void * pvRxData, size_t xBufferLengthBytes, BaseType_t * const pxHigherPriorityTaskWoken ) { StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength; configASSERT( pvRxData ); configASSERT( pxStreamBuffer ); /* This receive function is used by both message buffers, which store * discrete messages, and stream buffers, which store a continuous stream of * bytes. Discrete messages include an additional * sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the * message. */ if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) { xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH; } else { xBytesToStoreMessageLength = 0; } xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); /* Whether receiving a discrete message (where xBytesToStoreMessageLength * holds the number of bytes used to store the message length) or a stream of * bytes (where xBytesToStoreMessageLength is zero), the number of bytes * available must be greater than xBytesToStoreMessageLength to be able to * read bytes from the buffer. */ if( xBytesAvailable > xBytesToStoreMessageLength ) { xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable ); /* Was a task waiting for space in the buffer? */ if( xReceivedLength != ( size_t ) 0 ) { prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ); return xReceivedLength; } /*-----------------------------------------------------------*/ static size_t prvReadMessageFromBuffer( StreamBuffer_t * pxStreamBuffer, void * pvRxData, size_t xBufferLengthBytes, size_t xBytesAvailable ) { size_t xCount, xNextMessageLength; configMESSAGE_BUFFER_LENGTH_TYPE xTempNextMessageLength; size_t xNextTail = pxStreamBuffer->xTail; if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) { /* A discrete message is being received. First receive the length * of the message. */ xNextTail = prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempNextMessageLength, sbBYTES_TO_STORE_MESSAGE_LENGTH, xNextTail ); xNextMessageLength = ( size_t ) xTempNextMessageLength; /* Reduce the number of bytes available by the number of bytes just * read out. */ xBytesAvailable -= sbBYTES_TO_STORE_MESSAGE_LENGTH; /* Check there is enough space in the buffer provided by the * user. */ if( xNextMessageLength > xBufferLengthBytes ) { /* The user has provided insufficient space to read the message. */ xNextMessageLength = 0; } else { mtCOVERAGE_TEST_MARKER(); } } else { /* A stream of bytes is being received (as opposed to a discrete * message), so read as many bytes as possible. */ xNextMessageLength = xBufferLengthBytes; } /* Use the minimum of the wanted bytes and the available bytes. */ xCount = configMIN( xNextMessageLength, xBytesAvailable ); if( xCount != ( size_t ) 0 ) { /* Read the actual data and update the tail to mark the data as officially consumed. */ pxStreamBuffer->xTail = prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) pvRxData, xCount, xNextTail ); /*lint !e9079 Data storage area is implemented as uint8_t array for ease of sizing, indexing and alignment. */ } return xCount; } /*-----------------------------------------------------------*/ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) { const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; BaseType_t xReturn; size_t xTail; configASSERT( pxStreamBuffer ); /* True if no bytes are available. */ xTail = pxStreamBuffer->xTail; if( pxStreamBuffer->xHead == xTail ) { xReturn = pdTRUE; } else { xReturn = pdFALSE; } return xReturn; } /*-----------------------------------------------------------*/ BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) { BaseType_t xReturn; size_t xBytesToStoreMessageLength; const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; configASSERT( pxStreamBuffer ); /* This generic version of the receive function is used by both message * buffers, which store discrete messages, and stream buffers, which store a * continuous stream of bytes. Discrete messages include an additional * sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the message. */ if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) { xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH; } else { xBytesToStoreMessageLength = 0; } /* True if the available space equals zero. */ if( xStreamBufferSpacesAvailable( xStreamBuffer ) <= xBytesToStoreMessageLength ) { xReturn = pdTRUE; } else { xReturn = pdFALSE; } return xReturn; } /*-----------------------------------------------------------*/ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t * pxHigherPriorityTaskWoken ) { StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; BaseType_t xReturn; UBaseType_t uxSavedInterruptStatus; configASSERT( pxStreamBuffer ); uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); { if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) { ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, ( uint32_t ) 0, eNoAction, pxHigherPriorityTaskWoken ); ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; xReturn = pdTRUE; } else { xReturn = pdFALSE; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } /*-----------------------------------------------------------*/ BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t * pxHigherPriorityTaskWoken ) { StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; BaseType_t xReturn; UBaseType_t uxSavedInterruptStatus; configASSERT( pxStreamBuffer ); uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); { if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) { ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, ( uint32_t ) 0, eNoAction, pxHigherPriorityTaskWoken ); ( pxStreamBuffer )->xTaskWaitingToSend = NULL; xReturn = pdTRUE; } else { xReturn = pdFALSE; } } portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } /*-----------------------------------------------------------*/ static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, const uint8_t * pucData, size_t xCount, size_t xHead ) { size_t xFirstLength; configASSERT( xCount > ( size_t ) 0 ); /* Calculate the number of bytes that can be added in the first write - * which may be less than the total number of bytes that need to be added if * the buffer will wrap back to the beginning. */ xFirstLength = configMIN( pxStreamBuffer->xLength - xHead, xCount ); /* Write as many bytes as can be written in the first write. */ configASSERT( ( xHead + xFirstLength ) <= pxStreamBuffer->xLength ); ( void ) memcpy( ( void * ) ( &( pxStreamBuffer->pucBuffer[ xHead ] ) ), ( const void * ) pucData, xFirstLength ); /*lint !e9087 memcpy() requires void *. */ /* If the number of bytes written was less than the number that could be * written in the first write... */ if( xCount > xFirstLength ) { /* ...then write the remaining bytes to the start of the buffer. */ configASSERT( ( xCount - xFirstLength ) <= pxStreamBuffer->xLength ); ( void ) memcpy( ( void * ) pxStreamBuffer->pucBuffer, ( const void * ) &( pucData[ xFirstLength ] ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */ } else { mtCOVERAGE_TEST_MARKER(); } xHead += xCount; if( xHead >= pxStreamBuffer->xLength ) { xHead -= pxStreamBuffer->xLength; } else { mtCOVERAGE_TEST_MARKER(); } return xHead; } /*-----------------------------------------------------------*/ static size_t prvReadBytesFromBuffer( StreamBuffer_t * pxStreamBuffer, uint8_t * pucData, size_t xCount, size_t xTail ) { size_t xFirstLength; configASSERT( xCount != ( size_t ) 0 ); /* Calculate the number of bytes that can be read - which may be * less than the number wanted if the data wraps around to the start of * the buffer. */ xFirstLength = configMIN( pxStreamBuffer->xLength - xTail, xCount ); /* Obtain the number of bytes it is possible to obtain in the first * read. Asserts check bounds of read and write. */ configASSERT( xFirstLength <= xCount ); configASSERT( ( xTail + xFirstLength ) <= pxStreamBuffer->xLength ); ( void ) memcpy( ( void * ) pucData, ( const void * ) &( pxStreamBuffer->pucBuffer[ xTail ] ), xFirstLength ); /*lint !e9087 memcpy() requires void *. */ /* If the total number of wanted bytes is greater than the number * that could be read in the first read... */ if( xCount > xFirstLength ) { /* ...then read the remaining bytes from the start of the buffer. */ ( void ) memcpy( ( void * ) &( pucData[ xFirstLength ] ), ( void * ) ( pxStreamBuffer->pucBuffer ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */ } else { mtCOVERAGE_TEST_MARKER(); } /* Move the tail pointer to effectively remove the data read from the buffer. */ xTail += xCount; if( xTail >= pxStreamBuffer->xLength ) { xTail -= pxStreamBuffer->xLength; } return xTail; } /*-----------------------------------------------------------*/ static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) { /* Returns the distance between xTail and xHead. */ size_t xCount; xCount = pxStreamBuffer->xLength + pxStreamBuffer->xHead; xCount -= pxStreamBuffer->xTail; if( xCount >= pxStreamBuffer->xLength ) { xCount -= pxStreamBuffer->xLength; } else { mtCOVERAGE_TEST_MARKER(); } return xCount; } /*-----------------------------------------------------------*/ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, uint8_t * const pucBuffer, size_t xBufferSizeBytes, size_t xTriggerLevelBytes, uint8_t ucFlags, StreamBufferCallbackFunction_t pxSendCompletedCallback, StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) { /* Assert here is deliberately writing to the entire buffer to ensure it can * be written to without generating exceptions, and is setting the buffer to a * known value to assist in development/debugging. */ #if ( configASSERT_DEFINED == 1 ) { /* The value written just has to be identifiable when looking at the * memory. Don't use 0xA5 as that is the stack fill value and could * result in confusion as to what is actually being observed. */ const BaseType_t xWriteValue = 0x55; configASSERT( memset( pucBuffer, ( int ) xWriteValue, xBufferSizeBytes ) == pucBuffer ); } /*lint !e529 !e438 xWriteValue is only used if configASSERT() is defined. */ #endif ( void ) memset( ( void * ) pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); /*lint !e9087 memset() requires void *. */ pxStreamBuffer->pucBuffer = pucBuffer; pxStreamBuffer->xLength = xBufferSizeBytes; pxStreamBuffer->xTriggerLevelBytes = xTriggerLevelBytes; pxStreamBuffer->ucFlags = ucFlags; #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) { pxStreamBuffer->pxSendCompletedCallback = pxSendCompletedCallback; pxStreamBuffer->pxReceiveCompletedCallback = pxReceiveCompletedCallback; } #else { ( void ) pxSendCompletedCallback; ( void ) pxReceiveCompletedCallback; } #endif } #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) { return xStreamBuffer->uxStreamBufferNumber; } #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ #if ( configUSE_TRACE_FACILITY == 1 ) void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) { xStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber; } #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ #if ( configUSE_TRACE_FACILITY == 1 ) uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) { return( xStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ); } #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ ================================================ FILE: FreeRTOS-comparison/tasks.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* FreeRTOS includes. */ #include "FreeRTOS.h" #include "task.h" #include "timers.h" #include "stack_macros.h" /* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified * because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined * for the header files above, but not in this file, in order to generate the * correct privileged Vs unprivileged linkage and placement. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ /* Set configUSE_STATS_FORMATTING_FUNCTIONS to 2 to include the stats formatting * functions but without including stdio.h here. */ #if ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) /* At the bottom of this file are two optional functions that can be used * to generate human readable text from the raw data generated by the * uxTaskGetSystemState() function. Note the formatting functions are provided * for convenience only, and are NOT considered part of the kernel. */ #include #endif /* configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) */ #if ( configUSE_PREEMPTION == 0 ) /* If the cooperative scheduler is being used then a yield should not be * performed just because a higher priority task has been woken. */ #define taskYIELD_IF_USING_PREEMPTION() #else #define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() #endif /* Values that can be assigned to the ucNotifyState member of the TCB. */ #define taskNOT_WAITING_NOTIFICATION ( ( uint8_t ) 0 ) /* Must be zero as it is the initialised value. */ #define taskWAITING_NOTIFICATION ( ( uint8_t ) 1 ) #define taskNOTIFICATION_RECEIVED ( ( uint8_t ) 2 ) /* * The value used to fill the stack of a task when the task is created. This * is used purely for checking the high water mark for tasks. */ #define tskSTACK_FILL_BYTE ( 0xa5U ) /* Bits used to record how a task's stack and TCB were allocated. */ #define tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 0 ) #define tskSTATICALLY_ALLOCATED_STACK_ONLY ( ( uint8_t ) 1 ) #define tskSTATICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 2 ) /* If any of the following are set then task stacks are filled with a known * value so the high water mark can be determined. If none of the following are * set then don't fill the stack so there is no unnecessary dependency on memset. */ #if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) #define tskSET_NEW_STACKS_TO_KNOWN_VALUE 1 #else #define tskSET_NEW_STACKS_TO_KNOWN_VALUE 0 #endif /* * Macros used by vListTask to indicate which state a task is in. */ #define tskRUNNING_CHAR ( 'X' ) #define tskBLOCKED_CHAR ( 'B' ) #define tskREADY_CHAR ( 'R' ) #define tskDELETED_CHAR ( 'D' ) #define tskSUSPENDED_CHAR ( 'S' ) /* * Some kernel aware debuggers require the data the debugger needs access to to * be global, rather than file scope. */ #ifdef portREMOVE_STATIC_QUALIFIER #define static #endif /* The name allocated to the Idle task. This can be overridden by defining * configIDLE_TASK_NAME in FreeRTOSConfig.h. */ #ifndef configIDLE_TASK_NAME #define configIDLE_TASK_NAME "IDLE" #endif #if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is * performed in a generic way that is not optimised to any particular * microcontroller architecture. */ /* uxTopReadyPriority holds the priority of the highest priority ready * state task. */ #define taskRECORD_READY_PRIORITY( uxPriority ) \ { \ if( ( uxPriority ) > uxTopReadyPriority ) \ { \ uxTopReadyPriority = ( uxPriority ); \ } \ } /* taskRECORD_READY_PRIORITY */ /*-----------------------------------------------------------*/ #define taskSELECT_HIGHEST_PRIORITY_TASK() \ { \ UBaseType_t uxTopPriority = uxTopReadyPriority; \ \ /* Find the highest priority queue that contains ready tasks. */ \ while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) ) \ { \ configASSERT( uxTopPriority ); \ --uxTopPriority; \ } \ \ /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \ * the same priority get an equal share of the processor time. */ \ listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ uxTopReadyPriority = uxTopPriority; \ } /* taskSELECT_HIGHEST_PRIORITY_TASK */ /*-----------------------------------------------------------*/ /* Define away taskRESET_READY_PRIORITY() and portRESET_READY_PRIORITY() as * they are only required when a port optimised method of task selection is * being used. */ #define taskRESET_READY_PRIORITY( uxPriority ) #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority ) #else /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 1 then task selection is * performed in a way that is tailored to the particular microcontroller * architecture being used. */ /* A port optimised version is provided. Call the port defined macros. */ #define taskRECORD_READY_PRIORITY( uxPriority ) portRECORD_READY_PRIORITY( ( uxPriority ), uxTopReadyPriority ) /*-----------------------------------------------------------*/ #define taskSELECT_HIGHEST_PRIORITY_TASK() \ { \ UBaseType_t uxTopPriority; \ \ /* Find the highest priority list that contains ready tasks. */ \ portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \ configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \ listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ } /* taskSELECT_HIGHEST_PRIORITY_TASK() */ /*-----------------------------------------------------------*/ /* A port optimised version is provided, call it only if the TCB being reset * is being referenced from a ready list. If it is referenced from a delayed * or suspended list then it won't be in a ready list. */ #define taskRESET_READY_PRIORITY( uxPriority ) \ { \ if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == ( UBaseType_t ) 0 ) \ { \ portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) ); \ } \ } #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /*-----------------------------------------------------------*/ /* pxDelayedTaskList and pxOverflowDelayedTaskList are switched when the tick * count overflows. */ #define taskSWITCH_DELAYED_LISTS() \ { \ List_t * pxTemp; \ \ /* The delayed tasks list should be empty when the lists are switched. */ \ configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) ); \ \ pxTemp = pxDelayedTaskList; \ pxDelayedTaskList = pxOverflowDelayedTaskList; \ pxOverflowDelayedTaskList = pxTemp; \ xNumOfOverflows++; \ prvResetNextTaskUnblockTime(); \ } /*-----------------------------------------------------------*/ /* * Place the task represented by pxTCB into the appropriate ready list for * the task. It is inserted at the end of the list. */ #define prvAddTaskToReadyList( pxTCB ) \ traceMOVED_TASK_TO_READY_STATE( pxTCB ); \ taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \ listINSERT_END( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \ tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB ) /*-----------------------------------------------------------*/ /* * Several functions take a TaskHandle_t parameter that can optionally be NULL, * where NULL is used to indicate that the handle of the currently executing * task should be used in place of the parameter. This macro simply checks to * see if the parameter is NULL and returns a pointer to the appropriate TCB. */ #define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? pxCurrentTCB : ( pxHandle ) ) /* The item value of the event list item is normally used to hold the priority * of the task to which it belongs (coded to allow it to be held in reverse * priority order). However, it is occasionally borrowed for other purposes. It * is important its value is not updated due to a task priority change while it is * being used for another purpose. The following bit definition is used to inform * the scheduler that the value should not be changed - in which case it is the * responsibility of whichever module is using the value to ensure it gets set back * to its original value when it is released. */ #if ( configUSE_16_BIT_TICKS == 1 ) #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x8000U #else #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x80000000UL #endif /* * Task control block. A task control block (TCB) is allocated for each task, * and stores task state information, including a pointer to the task's context * (the task's run time environment, including register values) */ typedef struct tskTaskControlBlock /* The old naming convention is used to prevent breaking kernel aware debuggers. */ { volatile StackType_t * pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */ #if ( portUSING_MPU_WRAPPERS == 1 ) xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */ #endif ListItem_t xStateListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */ ListItem_t xEventListItem; /*< Used to reference a task from an event list. */ UBaseType_t uxPriority; /*< The priority of the task. 0 is the lowest priority. */ StackType_t * pxStack; /*< Points to the start of the stack. */ char pcTaskName[ configMAX_TASK_NAME_LEN ]; /*< Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) StackType_t * pxEndOfStack; /*< Points to the highest valid address for the stack. */ #endif #if ( portCRITICAL_NESTING_IN_TCB == 1 ) UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */ #endif #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */ UBaseType_t uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */ #endif #if ( configUSE_MUTEXES == 1 ) UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */ UBaseType_t uxMutexesHeld; #endif #if ( configUSE_APPLICATION_TASK_TAG == 1 ) TaskHookFunction_t pxTaskTag; #endif #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) void * pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; #endif #if ( configGENERATE_RUN_TIME_STATS == 1 ) configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */ #endif #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) configTLS_BLOCK_TYPE xTLSBlock; /*< Memory block used as Thread Local Storage (TLS) Block for the task. */ #endif #if ( configUSE_TASK_NOTIFICATIONS == 1 ) volatile uint32_t ulNotifiedValue[ configTASK_NOTIFICATION_ARRAY_ENTRIES ]; volatile uint8_t ucNotifyState[ configTASK_NOTIFICATION_ARRAY_ENTRIES ]; #endif /* See the comments in FreeRTOS.h with the definition of * tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */ #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */ #endif #if ( INCLUDE_xTaskAbortDelay == 1 ) uint8_t ucDelayAborted; #endif #if ( configUSE_POSIX_ERRNO == 1 ) int iTaskErrno; #endif } tskTCB; /* The old tskTCB name is maintained above then typedefed to the new TCB_t name * below to enable the use of older kernel aware debuggers. */ typedef tskTCB TCB_t; /*lint -save -e956 A manual analysis and inspection has been used to determine * which static variables must be declared volatile. */ portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; /* Lists for ready and blocked tasks. -------------------- * xDelayedTaskList1 and xDelayedTaskList2 could be moved to function scope but * doing so breaks some kernel aware debuggers and debuggers that rely on removing * the static qualifier. */ PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ]; /*< Prioritised ready tasks. */ PRIVILEGED_DATA static List_t xDelayedTaskList1; /*< Delayed tasks. */ PRIVILEGED_DATA static List_t xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */ PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ PRIVILEGED_DATA static List_t xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */ #if ( INCLUDE_vTaskDelete == 1 ) PRIVILEGED_DATA static List_t xTasksWaitingTermination; /*< Tasks that have been deleted - but their memory not yet freed. */ PRIVILEGED_DATA static volatile UBaseType_t uxDeletedTasksWaitingCleanUp = ( UBaseType_t ) 0U; #endif #if ( INCLUDE_vTaskSuspend == 1 ) PRIVILEGED_DATA static List_t xSuspendedTaskList; /*< Tasks that are currently suspended. */ #endif /* Global POSIX errno. Its value is changed upon context switching to match * the errno of the currently running task. */ #if ( configUSE_POSIX_ERRNO == 1 ) int FreeRTOS_errno = 0; #endif /* Other file private variables. --------------------------------*/ PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT; PRIVILEGED_DATA static volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY; PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning = pdFALSE; PRIVILEGED_DATA static volatile TickType_t xPendedTicks = ( TickType_t ) 0U; PRIVILEGED_DATA static volatile BaseType_t xYieldPending = pdFALSE; PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0; PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U; PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */ PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandle = NULL; /*< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */ /* Improve support for OpenOCD. The kernel tracks Ready tasks via priority lists. * For tracking the state of remote threads, OpenOCD uses uxTopUsedPriority * to determine the number of priority lists to read back from the remote target. */ const volatile UBaseType_t uxTopUsedPriority = configMAX_PRIORITIES - 1U; /* Context switches are held pending while the scheduler is suspended. Also, * interrupts must not manipulate the xStateListItem of a TCB, or any of the * lists the xStateListItem can be referenced from, if the scheduler is suspended. * If an interrupt needs to unblock a task while the scheduler is suspended then it * moves the task's event list item into the xPendingReadyList, ready for the * kernel to move the task from the pending ready list into the real ready list * when the scheduler is unsuspended. The pending ready list itself can only be * accessed from a critical section. */ PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t ) pdFALSE; #if ( configGENERATE_RUN_TIME_STATS == 1 ) /* Do not move these variables to function scope as doing so prevents the * code working with debuggers that need to remove the static qualifier. */ PRIVILEGED_DATA static configRUN_TIME_COUNTER_TYPE ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */ PRIVILEGED_DATA static volatile configRUN_TIME_COUNTER_TYPE ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */ #endif /*lint -restore */ /*-----------------------------------------------------------*/ /* File private functions. --------------------------------*/ /** * Utility task that simply returns pdTRUE if the task referenced by xTask is * currently in the Suspended state, or pdFALSE if the task referenced by xTask * is in any other state. */ #if ( INCLUDE_vTaskSuspend == 1 ) static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; #endif /* INCLUDE_vTaskSuspend */ /* * Utility to ready all the lists used by the scheduler. This is called * automatically upon the creation of the first task. */ static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION; /* * The idle task, which as all tasks is implemented as a never ending loop. * The idle task is automatically created and added to the ready lists upon * creation of the first user task. * * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific * language extensions. The equivalent prototype for this function is: * * void prvIdleTask( void *pvParameters ); * */ static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ) PRIVILEGED_FUNCTION; /* * Utility to free all memory allocated by the scheduler to hold a TCB, * including the stack pointed to by the TCB. * * This does not free memory allocated by the task itself (i.e. memory * allocated by calls to pvPortMalloc from within the tasks application code). */ #if ( INCLUDE_vTaskDelete == 1 ) static void prvDeleteTCB( TCB_t * pxTCB ) PRIVILEGED_FUNCTION; #endif /* * Used only by the idle task. This checks to see if anything has been placed * in the list of tasks waiting to be deleted. If so the task is cleaned up * and its TCB deleted. */ static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION; /* * The currently executing task is entering the Blocked state. Add the task to * either the current or the overflow delayed task list. */ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseType_t xCanBlockIndefinitely ) PRIVILEGED_FUNCTION; /* * Fills an TaskStatus_t structure with information on each task that is * referenced from the pxList list (which may be a ready list, a delayed list, * a suspended list, etc.). * * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM * NORMAL APPLICATION CODE. */ #if ( configUSE_TRACE_FACILITY == 1 ) static UBaseType_t prvListTasksWithinSingleList( TaskStatus_t * pxTaskStatusArray, List_t * pxList, eTaskState eState ) PRIVILEGED_FUNCTION; #endif /* * Searches pxList for a task with name pcNameToQuery - returning a handle to * the task if it is found, or NULL if the task is not found. */ #if ( INCLUDE_xTaskGetHandle == 1 ) static TCB_t * prvSearchForNameWithinSingleList( List_t * pxList, const char pcNameToQuery[] ) PRIVILEGED_FUNCTION; #endif /* * When a task is created, the stack of the task is filled with a known value. * This function determines the 'high water mark' of the task stack by * determining how much of the stack remains at the original preset value. */ #if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) PRIVILEGED_FUNCTION; #endif /* * Return the amount of time, in ticks, that will pass before the kernel will * next move a task from the Blocked state to the Running state. * * This conditional compilation should use inequality to 0, not equality to 1. * This is to ensure portSUPPRESS_TICKS_AND_SLEEP() can be called when user * defined low power mode implementations require configUSE_TICKLESS_IDLE to be * set to a value other than 1. */ #if ( configUSE_TICKLESS_IDLE != 0 ) static TickType_t prvGetExpectedIdleTime( void ) PRIVILEGED_FUNCTION; #endif /* * Set xNextTaskUnblockTime to the time at which the next Blocked state task * will exit the Blocked state. */ static void prvResetNextTaskUnblockTime( void ) PRIVILEGED_FUNCTION; #if ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) /* * Helper function used to pad task names with spaces when printing out * human readable tables of task information. */ static char * prvWriteNameToBuffer( char * pcBuffer, const char * pcTaskName ) PRIVILEGED_FUNCTION; #endif /* * Called after a Task_t structure has been allocated either statically or * dynamically to fill in the structure's members. */ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, TCB_t * pxNewTCB, const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; /* * Called after a new task has been created and initialised to place the task * under the control of the scheduler. */ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* * freertos_tasks_c_additions_init() should only be called if the user definable * macro FREERTOS_TASKS_C_ADDITIONS_INIT() is defined, as that is the only macro * called by the function. */ #ifdef FREERTOS_TASKS_C_ADDITIONS_INIT static void freertos_tasks_c_additions_init( void ) PRIVILEGED_FUNCTION; #endif /*-----------------------------------------------------------*/ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) { TCB_t * pxNewTCB; TaskHandle_t xReturn; configASSERT( puxStackBuffer != NULL ); configASSERT( pxTaskBuffer != NULL ); #if ( configASSERT_DEFINED == 1 ) { /* Sanity check that the size of the structure used to declare a * variable of type StaticTask_t equals the size of the real task * structure. */ volatile size_t xSize = sizeof( StaticTask_t ); configASSERT( xSize == sizeof( TCB_t ) ); ( void ) xSize; /* Prevent lint warning when configASSERT() is not used. */ } #endif /* configASSERT_DEFINED */ if( ( pxTaskBuffer != NULL ) && ( puxStackBuffer != NULL ) ) { /* The memory used for the task's TCB and stack are passed into this * function - use them. */ pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer; #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ { /* Tasks can be created statically or dynamically, so note this * task was created statically in case the task is later deleted. */ pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB; } #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB, NULL ); prvAddNewTaskToReadyList( pxNewTCB ); } else { xReturn = NULL; } return xReturn; } #endif /* SUPPORT_STATIC_ALLOCATION */ /*-----------------------------------------------------------*/ #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t * pxCreatedTask ) { TCB_t * pxNewTCB; BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; configASSERT( pxTaskDefinition->puxStackBuffer != NULL ); configASSERT( pxTaskDefinition->pxTaskBuffer != NULL ); if( ( pxTaskDefinition->puxStackBuffer != NULL ) && ( pxTaskDefinition->pxTaskBuffer != NULL ) ) { /* Allocate space for the TCB. Where the memory comes from depends * on the implementation of the port malloc function and whether or * not static allocation is being used. */ pxNewTCB = ( TCB_t * ) pxTaskDefinition->pxTaskBuffer; memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); /* Store the stack location in the TCB. */ pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer; #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) { /* Tasks can be created statically or dynamically, so note this * task was created statically in case the task is later deleted. */ pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB; } #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ prvInitialiseNewTask( pxTaskDefinition->pvTaskCode, pxTaskDefinition->pcName, ( uint32_t ) pxTaskDefinition->usStackDepth, pxTaskDefinition->pvParameters, pxTaskDefinition->uxPriority, pxCreatedTask, pxNewTCB, pxTaskDefinition->xRegions ); prvAddNewTaskToReadyList( pxNewTCB ); xReturn = pdPASS; } return xReturn; } #endif /* ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ /*-----------------------------------------------------------*/ #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t * pxCreatedTask ) { TCB_t * pxNewTCB; BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; configASSERT( pxTaskDefinition->puxStackBuffer ); if( pxTaskDefinition->puxStackBuffer != NULL ) { /* Allocate space for the TCB. Where the memory comes from depends * on the implementation of the port malloc function and whether or * not static allocation is being used. */ pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); if( pxNewTCB != NULL ) { memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); /* Store the stack location in the TCB. */ pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer; #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) { /* Tasks can be created statically or dynamically, so note * this task had a statically allocated stack in case it is * later deleted. The TCB was allocated dynamically. */ pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_ONLY; } #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ prvInitialiseNewTask( pxTaskDefinition->pvTaskCode, pxTaskDefinition->pcName, ( uint32_t ) pxTaskDefinition->usStackDepth, pxTaskDefinition->pvParameters, pxTaskDefinition->uxPriority, pxCreatedTask, pxNewTCB, pxTaskDefinition->xRegions ); prvAddNewTaskToReadyList( pxNewTCB ); xReturn = pdPASS; } } return xReturn; } #endif /* portUSING_MPU_WRAPPERS */ /*-----------------------------------------------------------*/ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const configSTACK_DEPTH_TYPE usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) { TCB_t * pxNewTCB; BaseType_t xReturn; /* If the stack grows down then allocate the stack then the TCB so the stack * does not grow into the TCB. Likewise if the stack grows up then allocate * the TCB then the stack. */ #if ( portSTACK_GROWTH > 0 ) { /* Allocate space for the TCB. Where the memory comes from depends on * the implementation of the port malloc function and whether or not static * allocation is being used. */ pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); if( pxNewTCB != NULL ) { memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); /* Allocate space for the stack used by the task being created. * The base of the stack memory stored in the TCB so the task can * be deleted later if required. */ pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocStack( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ if( pxNewTCB->pxStack == NULL ) { /* Could not allocate the stack. Delete the allocated TCB. */ vPortFree( pxNewTCB ); pxNewTCB = NULL; } } } #else /* portSTACK_GROWTH */ { StackType_t * pxStack; /* Allocate space for the stack used by the task being created. */ pxStack = pvPortMallocStack( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation is the stack. */ if( pxStack != NULL ) { /* Allocate space for the TCB. */ pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of TCB_t is always a pointer to the task's stack. */ if( pxNewTCB != NULL ) { memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); /* Store the stack location in the TCB. */ pxNewTCB->pxStack = pxStack; } else { /* The stack cannot be used as the TCB was not created. Free * it again. */ vPortFreeStack( pxStack ); } } else { pxNewTCB = NULL; } } #endif /* portSTACK_GROWTH */ if( pxNewTCB != NULL ) { #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e9029 !e731 Macro has been consolidated for readability reasons. */ { /* Tasks can be created statically or dynamically, so note this * task was created dynamically in case it is later deleted. */ pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB; } #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL ); prvAddNewTaskToReadyList( pxNewTCB ); xReturn = pdPASS; } else { xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; } return xReturn; } #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ /*-----------------------------------------------------------*/ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, TCB_t * pxNewTCB, const MemoryRegion_t * const xRegions ) { StackType_t * pxTopOfStack; UBaseType_t x; #if ( portUSING_MPU_WRAPPERS == 1 ) /* Should the task be created in privileged mode? */ BaseType_t xRunPrivileged; if( ( uxPriority & portPRIVILEGE_BIT ) != 0U ) { xRunPrivileged = pdTRUE; } else { xRunPrivileged = pdFALSE; } uxPriority &= ~portPRIVILEGE_BIT; #endif /* portUSING_MPU_WRAPPERS == 1 */ /* Avoid dependency on memset() if it is not required. */ #if ( tskSET_NEW_STACKS_TO_KNOWN_VALUE == 1 ) { /* Fill the stack with a known value to assist debugging. */ ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) ulStackDepth * sizeof( StackType_t ) ); } #endif /* tskSET_NEW_STACKS_TO_KNOWN_VALUE */ /* Calculate the top of stack address. This depends on whether the stack * grows from high memory to low (as per the 80x86) or vice versa. * portSTACK_GROWTH is used to make the result positive or negative as required * by the port. */ #if ( portSTACK_GROWTH < 0 ) { pxTopOfStack = &( pxNewTCB->pxStack[ ulStackDepth - ( uint32_t ) 1 ] ); pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); /*lint !e923 !e9033 !e9078 MISRA exception. Avoiding casts between pointers and integers is not practical. Size differences accounted for using portPOINTER_SIZE_TYPE type. Checked by assert(). */ /* Check the alignment of the calculated top of stack is correct. */ configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); #if ( configRECORD_STACK_HIGH_ADDRESS == 1 ) { /* Also record the stack's high address, which may assist * debugging. */ pxNewTCB->pxEndOfStack = pxTopOfStack; } #endif /* configRECORD_STACK_HIGH_ADDRESS */ } #else /* portSTACK_GROWTH */ { pxTopOfStack = pxNewTCB->pxStack; /* Check the alignment of the stack buffer is correct. */ configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxNewTCB->pxStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); /* The other extreme of the stack space is required if stack checking is * performed. */ pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( ulStackDepth - ( uint32_t ) 1 ); } #endif /* portSTACK_GROWTH */ /* Store the task name in the TCB. */ if( pcName != NULL ) { for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) { pxNewTCB->pcTaskName[ x ] = pcName[ x ]; /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than * configMAX_TASK_NAME_LEN characters just in case the memory after the * string is not accessible (extremely unlikely). */ if( pcName[ x ] == ( char ) 0x00 ) { break; } else { mtCOVERAGE_TEST_MARKER(); } } /* Ensure the name string is terminated in the case that the string length * was greater or equal to configMAX_TASK_NAME_LEN. */ pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0'; } else { mtCOVERAGE_TEST_MARKER(); } /* This is used as an array index so must ensure it's not too large. */ configASSERT( uxPriority < configMAX_PRIORITIES ); if( uxPriority >= ( UBaseType_t ) configMAX_PRIORITIES ) { uxPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U; } else { mtCOVERAGE_TEST_MARKER(); } pxNewTCB->uxPriority = uxPriority; #if ( configUSE_MUTEXES == 1 ) { pxNewTCB->uxBasePriority = uxPriority; } #endif /* configUSE_MUTEXES */ vListInitialiseItem( &( pxNewTCB->xStateListItem ) ); vListInitialiseItem( &( pxNewTCB->xEventListItem ) ); /* Set the pxNewTCB as a link back from the ListItem_t. This is so we can get * back to the containing TCB from a generic item in a list. */ listSET_LIST_ITEM_OWNER( &( pxNewTCB->xStateListItem ), pxNewTCB ); /* Event lists are always in priority order. */ listSET_LIST_ITEM_VALUE( &( pxNewTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ listSET_LIST_ITEM_OWNER( &( pxNewTCB->xEventListItem ), pxNewTCB ); #if ( portUSING_MPU_WRAPPERS == 1 ) { vPortStoreTaskMPUSettings( &( pxNewTCB->xMPUSettings ), xRegions, pxNewTCB->pxStack, ulStackDepth ); } #else { /* Avoid compiler warning about unreferenced parameter. */ ( void ) xRegions; } #endif #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) { /* Allocate and initialize memory for the task's TLS Block. */ configINIT_TLS_BLOCK( pxNewTCB->xTLSBlock ); } #endif /* Initialize the TCB stack to look as if the task was already running, * but had been interrupted by the scheduler. The return address is set * to the start of the task function. Once the stack has been initialised * the top of stack variable is updated. */ #if ( portUSING_MPU_WRAPPERS == 1 ) { /* If the port has capability to detect stack overflow, * pass the stack end address to the stack initialization * function as well. */ #if ( portHAS_STACK_OVERFLOW_CHECKING == 1 ) { #if ( portSTACK_GROWTH < 0 ) { pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxStack, pxTaskCode, pvParameters, xRunPrivileged ); } #else /* portSTACK_GROWTH */ { pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxEndOfStack, pxTaskCode, pvParameters, xRunPrivileged ); } #endif /* portSTACK_GROWTH */ } #else /* portHAS_STACK_OVERFLOW_CHECKING */ { pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged ); } #endif /* portHAS_STACK_OVERFLOW_CHECKING */ } #else /* portUSING_MPU_WRAPPERS */ { /* If the port has capability to detect stack overflow, * pass the stack end address to the stack initialization * function as well. */ #if ( portHAS_STACK_OVERFLOW_CHECKING == 1 ) { #if ( portSTACK_GROWTH < 0 ) { pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxStack, pxTaskCode, pvParameters ); } #else /* portSTACK_GROWTH */ { pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxEndOfStack, pxTaskCode, pvParameters ); } #endif /* portSTACK_GROWTH */ } #else /* portHAS_STACK_OVERFLOW_CHECKING */ { pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters ); } #endif /* portHAS_STACK_OVERFLOW_CHECKING */ } #endif /* portUSING_MPU_WRAPPERS */ if( pxCreatedTask != NULL ) { /* Pass the handle out in an anonymous way. The handle can be used to * change the created task's priority, delete the created task, etc.*/ *pxCreatedTask = ( TaskHandle_t ) pxNewTCB; } else { mtCOVERAGE_TEST_MARKER(); } } /*-----------------------------------------------------------*/ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) { /* Ensure interrupts don't access the task lists while the lists are being * updated. */ taskENTER_CRITICAL(); { uxCurrentNumberOfTasks++; if( pxCurrentTCB == NULL ) { /* There are no other tasks, or all the other tasks are in * the suspended state - make this the current task. */ pxCurrentTCB = pxNewTCB; if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 ) { /* This is the first task to be created so do the preliminary * initialisation required. We will not recover if this call * fails, but we will report the failure. */ prvInitialiseTaskLists(); } else { mtCOVERAGE_TEST_MARKER(); } } else { /* If the scheduler is not already running, make this task the * current task if it is the highest priority task to be created * so far. */ if( xSchedulerRunning == pdFALSE ) { if( pxCurrentTCB->uxPriority <= pxNewTCB->uxPriority ) { pxCurrentTCB = pxNewTCB; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } uxTaskNumber++; #if ( configUSE_TRACE_FACILITY == 1 ) { /* Add a counter into the TCB for tracing only. */ pxNewTCB->uxTCBNumber = uxTaskNumber; } #endif /* configUSE_TRACE_FACILITY */ traceTASK_CREATE( pxNewTCB ); prvAddTaskToReadyList( pxNewTCB ); portSETUP_TCB( pxNewTCB ); } taskEXIT_CRITICAL(); if( xSchedulerRunning != pdFALSE ) { /* If the created task is of a higher priority than the current task * then it should run now. */ if( pxCurrentTCB->uxPriority < pxNewTCB->uxPriority ) { taskYIELD_IF_USING_PREEMPTION(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } /*-----------------------------------------------------------*/ #if ( INCLUDE_vTaskDelete == 1 ) void vTaskDelete( TaskHandle_t xTaskToDelete ) { TCB_t * pxTCB; taskENTER_CRITICAL(); { /* If null is passed in here then it is the calling task that is * being deleted. */ pxTCB = prvGetTCBFromHandle( xTaskToDelete ); /* Remove task from the ready/delayed list. */ if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) { taskRESET_READY_PRIORITY( pxTCB->uxPriority ); } else { mtCOVERAGE_TEST_MARKER(); } /* Is the task waiting on an event also? */ if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) { ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); } else { mtCOVERAGE_TEST_MARKER(); } /* Increment the uxTaskNumber also so kernel aware debuggers can * detect that the task lists need re-generating. This is done before * portPRE_TASK_DELETE_HOOK() as in the Windows port that macro will * not return. */ uxTaskNumber++; if( pxTCB == pxCurrentTCB ) { /* A task is deleting itself. This cannot complete within the * task itself, as a context switch to another task is required. * Place the task in the termination list. The idle task will * check the termination list and free up any memory allocated by * the scheduler for the TCB and stack of the deleted task. */ vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xStateListItem ) ); /* Increment the ucTasksDeleted variable so the idle task knows * there is a task that has been deleted and that it should therefore * check the xTasksWaitingTermination list. */ ++uxDeletedTasksWaitingCleanUp; /* Call the delete hook before portPRE_TASK_DELETE_HOOK() as * portPRE_TASK_DELETE_HOOK() does not return in the Win32 port. */ traceTASK_DELETE( pxTCB ); /* The pre-delete hook is primarily for the Windows simulator, * in which Windows specific clean up operations are performed, * after which it is not possible to yield away from this task - * hence xYieldPending is used to latch that a context switch is * required. */ portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending ); } else { --uxCurrentNumberOfTasks; traceTASK_DELETE( pxTCB ); /* Reset the next expected unblock time in case it referred to * the task that has just been deleted. */ prvResetNextTaskUnblockTime(); } } taskEXIT_CRITICAL(); /* If the task is not deleting itself, call prvDeleteTCB from outside of * critical section. If a task deletes itself, prvDeleteTCB is called * from prvCheckTasksWaitingTermination which is called from Idle task. */ if( pxTCB != pxCurrentTCB ) { prvDeleteTCB( pxTCB ); } /* Force a reschedule if it is the currently running task that has just * been deleted. */ if( xSchedulerRunning != pdFALSE ) { if( pxTCB == pxCurrentTCB ) { configASSERT( uxSchedulerSuspended == 0 ); portYIELD_WITHIN_API(); } else { mtCOVERAGE_TEST_MARKER(); } } } #endif /* INCLUDE_vTaskDelete */ /*-----------------------------------------------------------*/ #if ( INCLUDE_xTaskDelayUntil == 1 ) BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) { TickType_t xTimeToWake; BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE; configASSERT( pxPreviousWakeTime ); configASSERT( ( xTimeIncrement > 0U ) ); configASSERT( uxSchedulerSuspended == 0 ); vTaskSuspendAll(); { /* Minor optimisation. The tick count cannot change in this * block. */ const TickType_t xConstTickCount = xTickCount; /* Generate the tick time at which the task wants to wake. */ xTimeToWake = *pxPreviousWakeTime + xTimeIncrement; if( xConstTickCount < *pxPreviousWakeTime ) { /* The tick count has overflowed since this function was * lasted called. In this case the only time we should ever * actually delay is if the wake time has also overflowed, * and the wake time is greater than the tick time. When this * is the case it is as if neither time had overflowed. */ if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) ) { xShouldDelay = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else { /* The tick time has not overflowed. In this case we will * delay if either the wake time has overflowed, and/or the * tick time is less than the wake time. */ if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) ) { xShouldDelay = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } /* Update the wake time ready for the next call. */ *pxPreviousWakeTime = xTimeToWake; if( xShouldDelay != pdFALSE ) { traceTASK_DELAY_UNTIL( xTimeToWake ); /* prvAddCurrentTaskToDelayedList() needs the block time, not * the time to wake, so subtract the current tick count. */ prvAddCurrentTaskToDelayedList( xTimeToWake - xConstTickCount, pdFALSE ); } else { mtCOVERAGE_TEST_MARKER(); } } xAlreadyYielded = xTaskResumeAll(); /* Force a reschedule if xTaskResumeAll has not already done so, we may * have put ourselves to sleep. */ if( xAlreadyYielded == pdFALSE ) { portYIELD_WITHIN_API(); } else { mtCOVERAGE_TEST_MARKER(); } return xShouldDelay; } #endif /* INCLUDE_xTaskDelayUntil */ /*-----------------------------------------------------------*/ #if ( INCLUDE_vTaskDelay == 1 ) void vTaskDelay( const TickType_t xTicksToDelay ) { BaseType_t xAlreadyYielded = pdFALSE; /* A delay time of zero just forces a reschedule. */ if( xTicksToDelay > ( TickType_t ) 0U ) { configASSERT( uxSchedulerSuspended == 0 ); vTaskSuspendAll(); { traceTASK_DELAY(); /* A task that is removed from the event list while the * scheduler is suspended will not get placed in the ready * list or removed from the blocked list until the scheduler * is resumed. * * This task cannot be in an event list as it is the currently * executing task. */ prvAddCurrentTaskToDelayedList( xTicksToDelay, pdFALSE ); } xAlreadyYielded = xTaskResumeAll(); } else { mtCOVERAGE_TEST_MARKER(); } /* Force a reschedule if xTaskResumeAll has not already done so, we may * have put ourselves to sleep. */ if( xAlreadyYielded == pdFALSE ) { portYIELD_WITHIN_API(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* INCLUDE_vTaskDelay */ /*-----------------------------------------------------------*/ #if ( ( INCLUDE_eTaskGetState == 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_xTaskAbortDelay == 1 ) ) eTaskState eTaskGetState( TaskHandle_t xTask ) { eTaskState eReturn; List_t const * pxStateList; List_t const * pxDelayedList; List_t const * pxOverflowedDelayedList; const TCB_t * const pxTCB = xTask; configASSERT( pxTCB ); if( pxTCB == pxCurrentTCB ) { /* The task calling this function is querying its own state. */ eReturn = eRunning; } else { taskENTER_CRITICAL(); { pxStateList = listLIST_ITEM_CONTAINER( &( pxTCB->xStateListItem ) ); pxDelayedList = pxDelayedTaskList; pxOverflowedDelayedList = pxOverflowDelayedTaskList; } taskEXIT_CRITICAL(); if( ( pxStateList == pxDelayedList ) || ( pxStateList == pxOverflowedDelayedList ) ) { /* The task being queried is referenced from one of the Blocked * lists. */ eReturn = eBlocked; } #if ( INCLUDE_vTaskSuspend == 1 ) else if( pxStateList == &xSuspendedTaskList ) { /* The task being queried is referenced from the suspended * list. Is it genuinely suspended or is it blocked * indefinitely? */ if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ) { #if ( configUSE_TASK_NOTIFICATIONS == 1 ) { BaseType_t x; /* The task does not appear on the event list item of * and of the RTOS objects, but could still be in the * blocked state if it is waiting on its notification * rather than waiting on an object. If not, is * suspended. */ eReturn = eSuspended; for( x = 0; x < configTASK_NOTIFICATION_ARRAY_ENTRIES; x++ ) { if( pxTCB->ucNotifyState[ x ] == taskWAITING_NOTIFICATION ) { eReturn = eBlocked; break; } } } #else /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ { eReturn = eSuspended; } #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ } else { eReturn = eBlocked; } } #endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ #if ( INCLUDE_vTaskDelete == 1 ) else if( ( pxStateList == &xTasksWaitingTermination ) || ( pxStateList == NULL ) ) { /* The task being queried is referenced from the deleted * tasks list, or it is not referenced from any lists at * all. */ eReturn = eDeleted; } #endif else /*lint !e525 Negative indentation is intended to make use of pre-processor clearer. */ { /* If the task is not in any other state, it must be in the * Ready (including pending ready) state. */ eReturn = eReady; } } return eReturn; } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */ #endif /* INCLUDE_eTaskGetState */ /*-----------------------------------------------------------*/ #if ( INCLUDE_uxTaskPriorityGet == 1 ) UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) { TCB_t const * pxTCB; UBaseType_t uxReturn; taskENTER_CRITICAL(); { /* If null is passed in here then it is the priority of the task * that called uxTaskPriorityGet() that is being queried. */ pxTCB = prvGetTCBFromHandle( xTask ); uxReturn = pxTCB->uxPriority; } taskEXIT_CRITICAL(); return uxReturn; } #endif /* INCLUDE_uxTaskPriorityGet */ /*-----------------------------------------------------------*/ #if ( INCLUDE_uxTaskPriorityGet == 1 ) UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) { TCB_t const * pxTCB; UBaseType_t uxReturn, uxSavedInterruptState; /* RTOS ports that support interrupt nesting have the concept of a * maximum system call (or maximum API call) interrupt priority. * Interrupts that are above the maximum system call priority are keep * permanently enabled, even when the RTOS kernel is in a critical section, * but cannot make any calls to FreeRTOS API functions. If configASSERT() * is defined in FreeRTOSConfig.h then * portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion * failure if a FreeRTOS API function is called from an interrupt that has * been assigned a priority above the configured maximum system call * priority. Only FreeRTOS functions that end in FromISR can be called * from interrupts that have been assigned a priority at or (logically) * below the maximum system call interrupt priority. FreeRTOS maintains a * separate interrupt safe API to ensure interrupt entry is as fast and as * simple as possible. More information (albeit Cortex-M specific) is * provided on the following link: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); uxSavedInterruptState = portSET_INTERRUPT_MASK_FROM_ISR(); { /* If null is passed in here then it is the priority of the calling * task that is being queried. */ pxTCB = prvGetTCBFromHandle( xTask ); uxReturn = pxTCB->uxPriority; } portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptState ); return uxReturn; } #endif /* INCLUDE_uxTaskPriorityGet */ /*-----------------------------------------------------------*/ #if ( INCLUDE_vTaskPrioritySet == 1 ) void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) { TCB_t * pxTCB; UBaseType_t uxCurrentBasePriority, uxPriorityUsedOnEntry; BaseType_t xYieldRequired = pdFALSE; configASSERT( uxNewPriority < configMAX_PRIORITIES ); /* Ensure the new priority is valid. */ if( uxNewPriority >= ( UBaseType_t ) configMAX_PRIORITIES ) { uxNewPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U; } else { mtCOVERAGE_TEST_MARKER(); } taskENTER_CRITICAL(); { /* If null is passed in here then it is the priority of the calling * task that is being changed. */ pxTCB = prvGetTCBFromHandle( xTask ); traceTASK_PRIORITY_SET( pxTCB, uxNewPriority ); #if ( configUSE_MUTEXES == 1 ) { uxCurrentBasePriority = pxTCB->uxBasePriority; } #else { uxCurrentBasePriority = pxTCB->uxPriority; } #endif if( uxCurrentBasePriority != uxNewPriority ) { /* The priority change may have readied a task of higher * priority than the calling task. */ if( uxNewPriority > uxCurrentBasePriority ) { if( pxTCB != pxCurrentTCB ) { /* The priority of a task other than the currently * running task is being raised. Is the priority being * raised above that of the running task? */ if( uxNewPriority >= pxCurrentTCB->uxPriority ) { xYieldRequired = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else { /* The priority of the running task is being raised, * but the running task must already be the highest * priority task able to run so no yield is required. */ } } else if( pxTCB == pxCurrentTCB ) { /* Setting the priority of the running task down means * there may now be another task of higher priority that * is ready to execute. */ xYieldRequired = pdTRUE; } else { /* Setting the priority of any other task down does not * require a yield as the running task must be above the * new priority of the task being modified. */ } /* Remember the ready list the task might be referenced from * before its uxPriority member is changed so the * taskRESET_READY_PRIORITY() macro can function correctly. */ uxPriorityUsedOnEntry = pxTCB->uxPriority; #if ( configUSE_MUTEXES == 1 ) { /* Only change the priority being used if the task is not * currently using an inherited priority. */ if( pxTCB->uxBasePriority == pxTCB->uxPriority ) { pxTCB->uxPriority = uxNewPriority; } else { mtCOVERAGE_TEST_MARKER(); } /* The base priority gets set whatever. */ pxTCB->uxBasePriority = uxNewPriority; } #else /* if ( configUSE_MUTEXES == 1 ) */ { pxTCB->uxPriority = uxNewPriority; } #endif /* if ( configUSE_MUTEXES == 1 ) */ /* Only reset the event list item value if the value is not * being used for anything else. */ if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) { listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxNewPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ } else { mtCOVERAGE_TEST_MARKER(); } /* If the task is in the blocked or suspended list we need do * nothing more than change its priority variable. However, if * the task is in a ready list it needs to be removed and placed * in the list appropriate to its new priority. */ if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xStateListItem ) ) != pdFALSE ) { /* The task is currently in its ready list - remove before * adding it to its new ready list. As we are in a critical * section we can do this even if the scheduler is suspended. */ if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) { /* It is known that the task is in its ready list so * there is no need to check again and the port level * reset macro can be called directly. */ portRESET_READY_PRIORITY( uxPriorityUsedOnEntry, uxTopReadyPriority ); } else { mtCOVERAGE_TEST_MARKER(); } prvAddTaskToReadyList( pxTCB ); } else { mtCOVERAGE_TEST_MARKER(); } if( xYieldRequired != pdFALSE ) { taskYIELD_IF_USING_PREEMPTION(); } else { mtCOVERAGE_TEST_MARKER(); } /* Remove compiler warning about unused variables when the port * optimised task selection is not being used. */ ( void ) uxPriorityUsedOnEntry; } } taskEXIT_CRITICAL(); } #endif /* INCLUDE_vTaskPrioritySet */ /*-----------------------------------------------------------*/ #if ( INCLUDE_vTaskSuspend == 1 ) void vTaskSuspend( TaskHandle_t xTaskToSuspend ) { TCB_t * pxTCB; taskENTER_CRITICAL(); { /* If null is passed in here then it is the running task that is * being suspended. */ pxTCB = prvGetTCBFromHandle( xTaskToSuspend ); traceTASK_SUSPEND( pxTCB ); /* Remove task from the ready/delayed list and place in the * suspended list. */ if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) { taskRESET_READY_PRIORITY( pxTCB->uxPriority ); } else { mtCOVERAGE_TEST_MARKER(); } /* Is the task waiting on an event also? */ if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) { ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); } else { mtCOVERAGE_TEST_MARKER(); } vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xStateListItem ) ); #if ( configUSE_TASK_NOTIFICATIONS == 1 ) { BaseType_t x; for( x = 0; x < configTASK_NOTIFICATION_ARRAY_ENTRIES; x++ ) { if( pxTCB->ucNotifyState[ x ] == taskWAITING_NOTIFICATION ) { /* The task was blocked to wait for a notification, but is * now suspended, so no notification was received. */ pxTCB->ucNotifyState[ x ] = taskNOT_WAITING_NOTIFICATION; } } } #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ } taskEXIT_CRITICAL(); if( xSchedulerRunning != pdFALSE ) { /* Reset the next expected unblock time in case it referred to the * task that is now in the Suspended state. */ taskENTER_CRITICAL(); { prvResetNextTaskUnblockTime(); } taskEXIT_CRITICAL(); } else { mtCOVERAGE_TEST_MARKER(); } if( pxTCB == pxCurrentTCB ) { if( xSchedulerRunning != pdFALSE ) { /* The current task has just been suspended. */ configASSERT( uxSchedulerSuspended == 0 ); portYIELD_WITHIN_API(); } else { /* The scheduler is not running, but the task that was pointed * to by pxCurrentTCB has just been suspended and pxCurrentTCB * must be adjusted to point to a different task. */ if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks ) /*lint !e931 Right has no side effect, just volatile. */ { /* No other tasks are ready, so set pxCurrentTCB back to * NULL so when the next task is created pxCurrentTCB will * be set to point to it no matter what its relative priority * is. */ pxCurrentTCB = NULL; } else { vTaskSwitchContext(); } } } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* INCLUDE_vTaskSuspend */ /*-----------------------------------------------------------*/ #if ( INCLUDE_vTaskSuspend == 1 ) static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) { BaseType_t xReturn = pdFALSE; const TCB_t * const pxTCB = xTask; /* Accesses xPendingReadyList so must be called from a critical * section. */ /* It does not make sense to check if the calling task is suspended. */ configASSERT( xTask ); /* Is the task being resumed actually in the suspended list? */ if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xStateListItem ) ) != pdFALSE ) { /* Has the task already been resumed from within an ISR? */ if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) == pdFALSE ) { /* Is it in the suspended list because it is in the Suspended * state, or because is is blocked with no timeout? */ if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) != pdFALSE ) /*lint !e961. The cast is only redundant when NULL is used. */ { xReturn = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } return xReturn; } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */ #endif /* INCLUDE_vTaskSuspend */ /*-----------------------------------------------------------*/ #if ( INCLUDE_vTaskSuspend == 1 ) void vTaskResume( TaskHandle_t xTaskToResume ) { TCB_t * const pxTCB = xTaskToResume; /* It does not make sense to resume the calling task. */ configASSERT( xTaskToResume ); /* The parameter cannot be NULL as it is impossible to resume the * currently executing task. */ if( ( pxTCB != pxCurrentTCB ) && ( pxTCB != NULL ) ) { taskENTER_CRITICAL(); { if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) { traceTASK_RESUME( pxTCB ); /* The ready list can be accessed even if the scheduler is * suspended because this is inside a critical section. */ ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); prvAddTaskToReadyList( pxTCB ); /* A higher priority task may have just been resumed. */ if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) { /* This yield may not cause the task just resumed to run, * but will leave the lists in the correct state for the * next yield. */ taskYIELD_IF_USING_PREEMPTION(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } taskEXIT_CRITICAL(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* INCLUDE_vTaskSuspend */ /*-----------------------------------------------------------*/ #if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) { BaseType_t xYieldRequired = pdFALSE; TCB_t * const pxTCB = xTaskToResume; UBaseType_t uxSavedInterruptStatus; configASSERT( xTaskToResume ); /* RTOS ports that support interrupt nesting have the concept of a * maximum system call (or maximum API call) interrupt priority. * Interrupts that are above the maximum system call priority are keep * permanently enabled, even when the RTOS kernel is in a critical section, * but cannot make any calls to FreeRTOS API functions. If configASSERT() * is defined in FreeRTOSConfig.h then * portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion * failure if a FreeRTOS API function is called from an interrupt that has * been assigned a priority above the configured maximum system call * priority. Only FreeRTOS functions that end in FromISR can be called * from interrupts that have been assigned a priority at or (logically) * below the maximum system call interrupt priority. FreeRTOS maintains a * separate interrupt safe API to ensure interrupt entry is as fast and as * simple as possible. More information (albeit Cortex-M specific) is * provided on the following link: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) { traceTASK_RESUME_FROM_ISR( pxTCB ); /* Check the ready lists can be accessed. */ if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) { /* Ready lists can be accessed so move the task from the * suspended list to the ready list directly. */ if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) { xYieldRequired = pdTRUE; /* Mark that a yield is pending in case the user is not * using the return value to initiate a context switch * from the ISR using portYIELD_FROM_ISR. */ xYieldPending = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); prvAddTaskToReadyList( pxTCB ); } else { /* The delayed or ready lists cannot be accessed so the task * is held in the pending ready list until the scheduler is * unsuspended. */ vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); } } else { mtCOVERAGE_TEST_MARKER(); } } portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); return xYieldRequired; } #endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */ /*-----------------------------------------------------------*/ void vTaskStartScheduler( void ) { BaseType_t xReturn; /* Add the idle task at the lowest priority. */ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) { StaticTask_t * pxIdleTaskTCBBuffer = NULL; StackType_t * pxIdleTaskStackBuffer = NULL; uint32_t ulIdleTaskStackSize; /* The Idle task is created using user provided RAM - obtain the * address of the RAM then create the idle task. */ vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize ); xIdleTaskHandle = xTaskCreateStatic( prvIdleTask, configIDLE_TASK_NAME, ulIdleTaskStackSize, ( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */ portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ pxIdleTaskStackBuffer, pxIdleTaskTCBBuffer ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ if( xIdleTaskHandle != NULL ) { xReturn = pdPASS; } else { xReturn = pdFAIL; } } #else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ { /* The Idle task is being created using dynamically allocated RAM. */ xReturn = xTaskCreate( prvIdleTask, configIDLE_TASK_NAME, configMINIMAL_STACK_SIZE, ( void * ) NULL, portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ &xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ } #endif /* configSUPPORT_STATIC_ALLOCATION */ #if ( configUSE_TIMERS == 1 ) { if( xReturn == pdPASS ) { xReturn = xTimerCreateTimerTask(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* configUSE_TIMERS */ if( xReturn == pdPASS ) { /* freertos_tasks_c_additions_init() should only be called if the user * definable macro FREERTOS_TASKS_C_ADDITIONS_INIT() is defined, as that is * the only macro called by the function. */ #ifdef FREERTOS_TASKS_C_ADDITIONS_INIT { freertos_tasks_c_additions_init(); } #endif /* Interrupts are turned off here, to ensure a tick does not occur * before or during the call to xPortStartScheduler(). The stacks of * the created tasks contain a status word with interrupts switched on * so interrupts will automatically get re-enabled when the first task * starts to run. */ portDISABLE_INTERRUPTS(); #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) { /* Switch C-Runtime's TLS Block to point to the TLS * block specific to the task that will run first. */ configSET_TLS_BLOCK( pxCurrentTCB->xTLSBlock ); } #endif xNextTaskUnblockTime = portMAX_DELAY; xSchedulerRunning = pdTRUE; xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT; /* If configGENERATE_RUN_TIME_STATS is defined then the following * macro must be defined to configure the timer/counter used to generate * the run time counter time base. NOTE: If configGENERATE_RUN_TIME_STATS * is set to 0 and the following line fails to build then ensure you do not * have portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() defined in your * FreeRTOSConfig.h file. */ portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(); traceTASK_SWITCHED_IN(); /* Setting up the timer tick is hardware specific and thus in the * portable interface. */ xPortStartScheduler(); /* In most cases, xPortStartScheduler() will not return. If it * returns pdTRUE then there was not enough heap memory available * to create either the Idle or the Timer task. If it returned * pdFALSE, then the application called xTaskEndScheduler(). * Most ports don't implement xTaskEndScheduler() as there is * nothing to return to. */ } else { /* This line will only be reached if the kernel could not be started, * because there was not enough FreeRTOS heap to create the idle task * or the timer task. */ configASSERT( xReturn != errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ); } /* Prevent compiler warnings if INCLUDE_xTaskGetIdleTaskHandle is set to 0, * meaning xIdleTaskHandle is not used anywhere else. */ ( void ) xIdleTaskHandle; /* OpenOCD makes use of uxTopUsedPriority for thread debugging. Prevent uxTopUsedPriority * from getting optimized out as it is no longer used by the kernel. */ ( void ) uxTopUsedPriority; } /*-----------------------------------------------------------*/ void vTaskEndScheduler( void ) { /* Stop the scheduler interrupts and call the portable scheduler end * routine so the original ISRs can be restored if necessary. The port * layer must ensure interrupts enable bit is left in the correct state. */ portDISABLE_INTERRUPTS(); xSchedulerRunning = pdFALSE; vPortEndScheduler(); } /*----------------------------------------------------------*/ void vTaskSuspendAll( void ) { /* A critical section is not required as the variable is of type * BaseType_t. Please read Richard Barry's reply in the following link to a * post in the FreeRTOS support forum before reporting this as a bug! - * https://goo.gl/wu4acr */ /* portSOFTWARE_BARRIER() is only implemented for emulated/simulated ports that * do not otherwise exhibit real time behaviour. */ portSOFTWARE_BARRIER(); /* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment * is used to allow calls to vTaskSuspendAll() to nest. */ ++uxSchedulerSuspended; /* Enforces ordering for ports and optimised compilers that may otherwise place * the above increment elsewhere. */ portMEMORY_BARRIER(); } /*----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE != 0 ) static TickType_t prvGetExpectedIdleTime( void ) { TickType_t xReturn; UBaseType_t uxHigherPriorityReadyTasks = pdFALSE; /* uxHigherPriorityReadyTasks takes care of the case where * configUSE_PREEMPTION is 0, so there may be tasks above the idle priority * task that are in the Ready state, even though the idle task is * running. */ #if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) { if( uxTopReadyPriority > tskIDLE_PRIORITY ) { uxHigherPriorityReadyTasks = pdTRUE; } } #else { const UBaseType_t uxLeastSignificantBit = ( UBaseType_t ) 0x01; /* When port optimised task selection is used the uxTopReadyPriority * variable is used as a bit map. If bits other than the least * significant bit are set then there are tasks that have a priority * above the idle priority that are in the Ready state. This takes * care of the case where the co-operative scheduler is in use. */ if( uxTopReadyPriority > uxLeastSignificantBit ) { uxHigherPriorityReadyTasks = pdTRUE; } } #endif /* if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) */ if( pxCurrentTCB->uxPriority > tskIDLE_PRIORITY ) { xReturn = 0; } else if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > 1 ) { /* There are other idle priority tasks in the ready state. If * time slicing is used then the very next tick interrupt must be * processed. */ xReturn = 0; } else if( uxHigherPriorityReadyTasks != pdFALSE ) { /* There are tasks in the Ready state that have a priority above the * idle priority. This path can only be reached if * configUSE_PREEMPTION is 0. */ xReturn = 0; } else { xReturn = xNextTaskUnblockTime - xTickCount; } return xReturn; } #endif /* configUSE_TICKLESS_IDLE */ /*----------------------------------------------------------*/ BaseType_t xTaskResumeAll( void ) { TCB_t * pxTCB = NULL; BaseType_t xAlreadyYielded = pdFALSE; /* If uxSchedulerSuspended is zero then this function does not match a * previous call to vTaskSuspendAll(). */ configASSERT( uxSchedulerSuspended ); /* It is possible that an ISR caused a task to be removed from an event * list while the scheduler was suspended. If this was the case then the * removed task will have been added to the xPendingReadyList. Once the * scheduler has been resumed it is safe to move all the pending ready * tasks from this list into their appropriate ready list. */ taskENTER_CRITICAL(); { --uxSchedulerSuspended; if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) { if( uxCurrentNumberOfTasks > ( UBaseType_t ) 0U ) { /* Move any readied tasks from the pending list into the * appropriate ready list. */ while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE ) { pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ listREMOVE_ITEM( &( pxTCB->xEventListItem ) ); portMEMORY_BARRIER(); listREMOVE_ITEM( &( pxTCB->xStateListItem ) ); prvAddTaskToReadyList( pxTCB ); /* If the moved task has a priority higher than or equal to * the current task then a yield must be performed. */ if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) { xYieldPending = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } if( pxTCB != NULL ) { /* A task was unblocked while the scheduler was suspended, * which may have prevented the next unblock time from being * re-calculated, in which case re-calculate it now. Mainly * important for low power tickless implementations, where * this can prevent an unnecessary exit from low power * state. */ prvResetNextTaskUnblockTime(); } /* If any ticks occurred while the scheduler was suspended then * they should be processed now. This ensures the tick count does * not slip, and that any delayed tasks are resumed at the correct * time. */ { TickType_t xPendedCounts = xPendedTicks; /* Non-volatile copy. */ if( xPendedCounts > ( TickType_t ) 0U ) { do { if( xTaskIncrementTick() != pdFALSE ) { xYieldPending = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } --xPendedCounts; } while( xPendedCounts > ( TickType_t ) 0U ); xPendedTicks = 0; } else { mtCOVERAGE_TEST_MARKER(); } } if( xYieldPending != pdFALSE ) { #if ( configUSE_PREEMPTION != 0 ) { xAlreadyYielded = pdTRUE; } #endif taskYIELD_IF_USING_PREEMPTION(); } else { mtCOVERAGE_TEST_MARKER(); } } } else { mtCOVERAGE_TEST_MARKER(); } } taskEXIT_CRITICAL(); return xAlreadyYielded; } /*-----------------------------------------------------------*/ TickType_t xTaskGetTickCount( void ) { TickType_t xTicks; /* Critical section required if running on a 16 bit processor. */ portTICK_TYPE_ENTER_CRITICAL(); { xTicks = xTickCount; } portTICK_TYPE_EXIT_CRITICAL(); return xTicks; } /*-----------------------------------------------------------*/ TickType_t xTaskGetTickCountFromISR( void ) { TickType_t xReturn; UBaseType_t uxSavedInterruptStatus; /* RTOS ports that support interrupt nesting have the concept of a maximum * system call (or maximum API call) interrupt priority. Interrupts that are * above the maximum system call priority are kept permanently enabled, even * when the RTOS kernel is in a critical section, but cannot make any calls to * FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h * then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion * failure if a FreeRTOS API function is called from an interrupt that has been * assigned a priority above the configured maximum system call priority. * Only FreeRTOS functions that end in FromISR can be called from interrupts * that have been assigned a priority at or (logically) below the maximum * system call interrupt priority. FreeRTOS maintains a separate interrupt * safe API to ensure interrupt entry is as fast and as simple as possible. * More information (albeit Cortex-M specific) is provided on the following * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); uxSavedInterruptStatus = portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR(); { xReturn = xTickCount; } portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } /*-----------------------------------------------------------*/ UBaseType_t uxTaskGetNumberOfTasks( void ) { /* A critical section is not required because the variables are of type * BaseType_t. */ return uxCurrentNumberOfTasks; } /*-----------------------------------------------------------*/ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ { TCB_t * pxTCB; /* If null is passed in here then the name of the calling task is being * queried. */ pxTCB = prvGetTCBFromHandle( xTaskToQuery ); configASSERT( pxTCB ); return &( pxTCB->pcTaskName[ 0 ] ); } /*-----------------------------------------------------------*/ #if ( INCLUDE_xTaskGetHandle == 1 ) static TCB_t * prvSearchForNameWithinSingleList( List_t * pxList, const char pcNameToQuery[] ) { TCB_t * pxNextTCB; TCB_t * pxFirstTCB; TCB_t * pxReturn = NULL; UBaseType_t x; char cNextChar; BaseType_t xBreakLoop; /* This function is called with the scheduler suspended. */ if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) { listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ do { listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ /* Check each character in the name looking for a match or * mismatch. */ xBreakLoop = pdFALSE; for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) { cNextChar = pxNextTCB->pcTaskName[ x ]; if( cNextChar != pcNameToQuery[ x ] ) { /* Characters didn't match. */ xBreakLoop = pdTRUE; } else if( cNextChar == ( char ) 0x00 ) { /* Both strings terminated, a match must have been * found. */ pxReturn = pxNextTCB; xBreakLoop = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } if( xBreakLoop != pdFALSE ) { break; } } if( pxReturn != NULL ) { /* The handle has been found. */ break; } } while( pxNextTCB != pxFirstTCB ); } else { mtCOVERAGE_TEST_MARKER(); } return pxReturn; } #endif /* INCLUDE_xTaskGetHandle */ /*-----------------------------------------------------------*/ #if ( INCLUDE_xTaskGetHandle == 1 ) TaskHandle_t xTaskGetHandle( const char * pcNameToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ { UBaseType_t uxQueue = configMAX_PRIORITIES; TCB_t * pxTCB; /* Task names will be truncated to configMAX_TASK_NAME_LEN - 1 bytes. */ configASSERT( strlen( pcNameToQuery ) < configMAX_TASK_NAME_LEN ); vTaskSuspendAll(); { /* Search the ready lists. */ do { uxQueue--; pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) &( pxReadyTasksLists[ uxQueue ] ), pcNameToQuery ); if( pxTCB != NULL ) { /* Found the handle. */ break; } } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ /* Search the delayed lists. */ if( pxTCB == NULL ) { pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxDelayedTaskList, pcNameToQuery ); } if( pxTCB == NULL ) { pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxOverflowDelayedTaskList, pcNameToQuery ); } #if ( INCLUDE_vTaskSuspend == 1 ) { if( pxTCB == NULL ) { /* Search the suspended list. */ pxTCB = prvSearchForNameWithinSingleList( &xSuspendedTaskList, pcNameToQuery ); } } #endif #if ( INCLUDE_vTaskDelete == 1 ) { if( pxTCB == NULL ) { /* Search the deleted list. */ pxTCB = prvSearchForNameWithinSingleList( &xTasksWaitingTermination, pcNameToQuery ); } } #endif } ( void ) xTaskResumeAll(); return pxTCB; } #endif /* INCLUDE_xTaskGetHandle */ /*-----------------------------------------------------------*/ #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) { UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES; vTaskSuspendAll(); { /* Is there a space in the array for each task in the system? */ if( uxArraySize >= uxCurrentNumberOfTasks ) { /* Fill in an TaskStatus_t structure with information on each * task in the Ready state. */ do { uxQueue--; uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &( pxReadyTasksLists[ uxQueue ] ), eReady ); } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ /* Fill in an TaskStatus_t structure with information on each * task in the Blocked state. */ uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxDelayedTaskList, eBlocked ); uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxOverflowDelayedTaskList, eBlocked ); #if ( INCLUDE_vTaskDelete == 1 ) { /* Fill in an TaskStatus_t structure with information on * each task that has been deleted but not yet cleaned up. */ uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xTasksWaitingTermination, eDeleted ); } #endif #if ( INCLUDE_vTaskSuspend == 1 ) { /* Fill in an TaskStatus_t structure with information on * each task in the Suspended state. */ uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xSuspendedTaskList, eSuspended ); } #endif #if ( configGENERATE_RUN_TIME_STATS == 1 ) { if( pulTotalRunTime != NULL ) { #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE portALT_GET_RUN_TIME_COUNTER_VALUE( ( *pulTotalRunTime ) ); #else *pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); #endif } } #else /* if ( configGENERATE_RUN_TIME_STATS == 1 ) */ { if( pulTotalRunTime != NULL ) { *pulTotalRunTime = 0; } } #endif /* if ( configGENERATE_RUN_TIME_STATS == 1 ) */ } else { mtCOVERAGE_TEST_MARKER(); } } ( void ) xTaskResumeAll(); return uxTask; } #endif /* configUSE_TRACE_FACILITY */ /*----------------------------------------------------------*/ #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) TaskHandle_t xTaskGetIdleTaskHandle( void ) { /* If xTaskGetIdleTaskHandle() is called before the scheduler has been * started, then xIdleTaskHandle will be NULL. */ configASSERT( ( xIdleTaskHandle != NULL ) ); return xIdleTaskHandle; } #endif /* INCLUDE_xTaskGetIdleTaskHandle */ /*----------------------------------------------------------*/ /* This conditional compilation should use inequality to 0, not equality to 1. * This is to ensure vTaskStepTick() is available when user defined low power mode * implementations require configUSE_TICKLESS_IDLE to be set to a value other than * 1. */ #if ( configUSE_TICKLESS_IDLE != 0 ) void vTaskStepTick( TickType_t xTicksToJump ) { /* Correct the tick count value after a period during which the tick * was suppressed. Note this does *not* call the tick hook function for * each stepped tick. */ configASSERT( ( xTickCount + xTicksToJump ) <= xNextTaskUnblockTime ); if( ( xTickCount + xTicksToJump ) == xNextTaskUnblockTime ) { /* Arrange for xTickCount to reach xNextTaskUnblockTime in * xTaskIncrementTick() when the scheduler resumes. This ensures * that any delayed tasks are resumed at the correct time. */ configASSERT( uxSchedulerSuspended ); configASSERT( xTicksToJump != ( TickType_t ) 0 ); /* Prevent the tick interrupt modifying xPendedTicks simultaneously. */ taskENTER_CRITICAL(); { xPendedTicks++; } taskEXIT_CRITICAL(); xTicksToJump--; } else { mtCOVERAGE_TEST_MARKER(); } xTickCount += xTicksToJump; traceINCREASE_TICK_COUNT( xTicksToJump ); } #endif /* configUSE_TICKLESS_IDLE */ /*----------------------------------------------------------*/ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) { BaseType_t xYieldOccurred; /* Must not be called with the scheduler suspended as the implementation * relies on xPendedTicks being wound down to 0 in xTaskResumeAll(). */ configASSERT( uxSchedulerSuspended == 0 ); /* Use xPendedTicks to mimic xTicksToCatchUp number of ticks occurring when * the scheduler is suspended so the ticks are executed in xTaskResumeAll(). */ vTaskSuspendAll(); /* Prevent the tick interrupt modifying xPendedTicks simultaneously. */ taskENTER_CRITICAL(); { xPendedTicks += xTicksToCatchUp; } taskEXIT_CRITICAL(); xYieldOccurred = xTaskResumeAll(); return xYieldOccurred; } /*----------------------------------------------------------*/ #if ( INCLUDE_xTaskAbortDelay == 1 ) BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) { TCB_t * pxTCB = xTask; BaseType_t xReturn; configASSERT( pxTCB ); vTaskSuspendAll(); { /* A task can only be prematurely removed from the Blocked state if * it is actually in the Blocked state. */ if( eTaskGetState( xTask ) == eBlocked ) { xReturn = pdPASS; /* Remove the reference to the task from the blocked list. An * interrupt won't touch the xStateListItem because the * scheduler is suspended. */ ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); /* Is the task waiting on an event also? If so remove it from * the event list too. Interrupts can touch the event list item, * even though the scheduler is suspended, so a critical section * is used. */ taskENTER_CRITICAL(); { if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) { ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); /* This lets the task know it was forcibly removed from the * blocked state so it should not re-evaluate its block time and * then block again. */ pxTCB->ucDelayAborted = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } taskEXIT_CRITICAL(); /* Place the unblocked task into the appropriate ready list. */ prvAddTaskToReadyList( pxTCB ); /* A task being unblocked cannot cause an immediate context * switch if preemption is turned off. */ #if ( configUSE_PREEMPTION == 1 ) { /* Preemption is on, but a context switch should only be * performed if the unblocked task has a priority that is * higher than the currently executing task. */ if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) { /* Pend the yield to be performed when the scheduler * is unsuspended. */ xYieldPending = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* configUSE_PREEMPTION */ } else { xReturn = pdFAIL; } } ( void ) xTaskResumeAll(); return xReturn; } #endif /* INCLUDE_xTaskAbortDelay */ /*----------------------------------------------------------*/ BaseType_t xTaskIncrementTick( void ) { TCB_t * pxTCB; TickType_t xItemValue; BaseType_t xSwitchRequired = pdFALSE; /* Called by the portable layer each time a tick interrupt occurs. * Increments the tick then checks to see if the new tick value will cause any * tasks to be unblocked. */ traceTASK_INCREMENT_TICK( xTickCount ); if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) { /* Minor optimisation. The tick count cannot change in this * block. */ const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1; /* Increment the RTOS tick, switching the delayed and overflowed * delayed lists if it wraps to 0. */ xTickCount = xConstTickCount; if( xConstTickCount == ( TickType_t ) 0U ) /*lint !e774 'if' does not always evaluate to false as it is looking for an overflow. */ { taskSWITCH_DELAYED_LISTS(); } else { mtCOVERAGE_TEST_MARKER(); } /* See if this tick has made a timeout expire. Tasks are stored in * the queue in the order of their wake time - meaning once one task * has been found whose block time has not expired there is no need to * look any further down the list. */ if( xConstTickCount >= xNextTaskUnblockTime ) { for( ; ; ) { if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) { /* The delayed list is empty. Set xNextTaskUnblockTime * to the maximum possible value so it is extremely * unlikely that the * if( xTickCount >= xNextTaskUnblockTime ) test will pass * next time through. */ xNextTaskUnblockTime = portMAX_DELAY; /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ break; } else { /* The delayed list is not empty, get the value of the * item at the head of the delayed list. This is the time * at which the task at the head of the delayed list must * be removed from the Blocked state. */ pxTCB = listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ) ); if( xConstTickCount < xItemValue ) { /* It is not time to unblock this item yet, but the * item value is the time at which the task at the head * of the blocked list must be removed from the Blocked * state - so record the item value in * xNextTaskUnblockTime. */ xNextTaskUnblockTime = xItemValue; break; /*lint !e9011 Code structure here is deemed easier to understand with multiple breaks. */ } else { mtCOVERAGE_TEST_MARKER(); } /* It is time to remove the item from the Blocked state. */ listREMOVE_ITEM( &( pxTCB->xStateListItem ) ); /* Is the task waiting on an event also? If so remove * it from the event list. */ if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) { listREMOVE_ITEM( &( pxTCB->xEventListItem ) ); } else { mtCOVERAGE_TEST_MARKER(); } /* Place the unblocked task into the appropriate ready * list. */ prvAddTaskToReadyList( pxTCB ); /* A task being unblocked cannot cause an immediate * context switch if preemption is turned off. */ #if ( configUSE_PREEMPTION == 1 ) { /* Preemption is on, but a context switch should * only be performed if the unblocked task's * priority is higher than the currently executing * task. * The case of equal priority tasks sharing * processing time (which happens when both * preemption and time slicing are on) is * handled below.*/ if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) { xSwitchRequired = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* configUSE_PREEMPTION */ } } } /* Tasks of equal priority to the currently running task will share * processing time (time slice) if preemption is on, and the application * writer has not explicitly turned time slicing off. */ #if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) { if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > ( UBaseType_t ) 1 ) { xSwitchRequired = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */ #if ( configUSE_TICK_HOOK == 1 ) { /* Guard against the tick hook being called when the pended tick * count is being unwound (when the scheduler is being unlocked). */ if( xPendedTicks == ( TickType_t ) 0 ) { vApplicationTickHook(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* configUSE_TICK_HOOK */ #if ( configUSE_PREEMPTION == 1 ) { if( xYieldPending != pdFALSE ) { xSwitchRequired = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* configUSE_PREEMPTION */ } else { ++xPendedTicks; /* The tick hook gets called at regular intervals, even if the * scheduler is locked. */ #if ( configUSE_TICK_HOOK == 1 ) { vApplicationTickHook(); } #endif } return xSwitchRequired; } /*-----------------------------------------------------------*/ #if ( configUSE_APPLICATION_TASK_TAG == 1 ) void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) { TCB_t * xTCB; /* If xTask is NULL then it is the task hook of the calling task that is * getting set. */ if( xTask == NULL ) { xTCB = ( TCB_t * ) pxCurrentTCB; } else { xTCB = xTask; } /* Save the hook function in the TCB. A critical section is required as * the value can be accessed from an interrupt. */ taskENTER_CRITICAL(); { xTCB->pxTaskTag = pxHookFunction; } taskEXIT_CRITICAL(); } #endif /* configUSE_APPLICATION_TASK_TAG */ /*-----------------------------------------------------------*/ #if ( configUSE_APPLICATION_TASK_TAG == 1 ) TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) { TCB_t * pxTCB; TaskHookFunction_t xReturn; /* If xTask is NULL then set the calling task's hook. */ pxTCB = prvGetTCBFromHandle( xTask ); /* Save the hook function in the TCB. A critical section is required as * the value can be accessed from an interrupt. */ taskENTER_CRITICAL(); { xReturn = pxTCB->pxTaskTag; } taskEXIT_CRITICAL(); return xReturn; } #endif /* configUSE_APPLICATION_TASK_TAG */ /*-----------------------------------------------------------*/ #if ( configUSE_APPLICATION_TASK_TAG == 1 ) TaskHookFunction_t xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) { TCB_t * pxTCB; TaskHookFunction_t xReturn; UBaseType_t uxSavedInterruptStatus; /* If xTask is NULL then set the calling task's hook. */ pxTCB = prvGetTCBFromHandle( xTask ); /* Save the hook function in the TCB. A critical section is required as * the value can be accessed from an interrupt. */ uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { xReturn = pxTCB->pxTaskTag; } portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } #endif /* configUSE_APPLICATION_TASK_TAG */ /*-----------------------------------------------------------*/ #if ( configUSE_APPLICATION_TASK_TAG == 1 ) BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void * pvParameter ) { TCB_t * xTCB; BaseType_t xReturn; /* If xTask is NULL then we are calling our own task hook. */ if( xTask == NULL ) { xTCB = pxCurrentTCB; } else { xTCB = xTask; } if( xTCB->pxTaskTag != NULL ) { xReturn = xTCB->pxTaskTag( pvParameter ); } else { xReturn = pdFAIL; } return xReturn; } #endif /* configUSE_APPLICATION_TASK_TAG */ /*-----------------------------------------------------------*/ void vTaskSwitchContext( void ) { if( uxSchedulerSuspended != ( UBaseType_t ) pdFALSE ) { /* The scheduler is currently suspended - do not allow a context * switch. */ xYieldPending = pdTRUE; } else { xYieldPending = pdFALSE; traceTASK_SWITCHED_OUT(); #if ( configGENERATE_RUN_TIME_STATS == 1 ) { #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); #else ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); #endif /* Add the amount of time the task has been running to the * accumulated time so far. The time the task started running was * stored in ulTaskSwitchedInTime. Note that there is no overflow * protection here so count values are only valid until the timer * overflows. The guard against negative values is to protect * against suspect run time stat counter implementations - which * are provided by the application, not the kernel. */ if( ulTotalRunTime > ulTaskSwitchedInTime ) { pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime ); } else { mtCOVERAGE_TEST_MARKER(); } ulTaskSwitchedInTime = ulTotalRunTime; } #endif /* configGENERATE_RUN_TIME_STATS */ /* Check for stack overflow, if configured. */ taskCHECK_FOR_STACK_OVERFLOW(); /* Before the currently running task is switched out, save its errno. */ #if ( configUSE_POSIX_ERRNO == 1 ) { pxCurrentTCB->iTaskErrno = FreeRTOS_errno; } #endif /* Select a new task to run using either the generic C or port * optimised asm code. */ taskSELECT_HIGHEST_PRIORITY_TASK(); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ traceTASK_SWITCHED_IN(); /* After the new task is switched in, update the global errno. */ #if ( configUSE_POSIX_ERRNO == 1 ) { FreeRTOS_errno = pxCurrentTCB->iTaskErrno; } #endif #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) { /* Switch C-Runtime's TLS Block to point to the TLS * Block specific to this task. */ configSET_TLS_BLOCK( pxCurrentTCB->xTLSBlock ); } #endif } } /*-----------------------------------------------------------*/ void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait ) { configASSERT( pxEventList ); /* THIS FUNCTION MUST BE CALLED WITH EITHER INTERRUPTS DISABLED OR THE * SCHEDULER SUSPENDED AND THE QUEUE BEING ACCESSED LOCKED. */ /* Place the event list item of the TCB in the appropriate event list. * This is placed in the list in priority order so the highest priority task * is the first to be woken by the event. * * Note: Lists are sorted in ascending order by ListItem_t.xItemValue. * Normally, the xItemValue of a TCB's ListItem_t members is: * xItemValue = ( configMAX_PRIORITIES - uxPriority ) * Therefore, the event list is sorted in descending priority order. * * The queue that contains the event list is locked, preventing * simultaneous access from interrupts. */ vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) ); prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); } /*-----------------------------------------------------------*/ void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait ) { configASSERT( pxEventList ); /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by * the event groups implementation. */ configASSERT( uxSchedulerSuspended != 0 ); /* Store the item value in the event list item. It is safe to access the * event list item here as interrupts won't access the event list item of a * task that is not in the Blocked state. */ listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE ); /* Place the event list item of the TCB at the end of the appropriate event * list. It is safe to access the event list here because it is part of an * event group implementation - and interrupts don't access event groups * directly (instead they access them indirectly by pending function calls to * the task level). */ listINSERT_END( pxEventList, &( pxCurrentTCB->xEventListItem ) ); prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); } /*-----------------------------------------------------------*/ #if ( configUSE_TIMERS == 1 ) void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) { configASSERT( pxEventList ); /* This function should not be called by application code hence the * 'Restricted' in its name. It is not part of the public API. It is * designed for use by kernel code, and has special calling requirements - * it should be called with the scheduler suspended. */ /* Place the event list item of the TCB in the appropriate event list. * In this case it is assume that this is the only task that is going to * be waiting on this event list, so the faster vListInsertEnd() function * can be used in place of vListInsert. */ listINSERT_END( pxEventList, &( pxCurrentTCB->xEventListItem ) ); /* If the task should block indefinitely then set the block time to a * value that will be recognised as an indefinite delay inside the * prvAddCurrentTaskToDelayedList() function. */ if( xWaitIndefinitely != pdFALSE ) { xTicksToWait = portMAX_DELAY; } traceTASK_DELAY_UNTIL( ( xTickCount + xTicksToWait ) ); prvAddCurrentTaskToDelayedList( xTicksToWait, xWaitIndefinitely ); } #endif /* configUSE_TIMERS */ /*-----------------------------------------------------------*/ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) { TCB_t * pxUnblockedTCB; BaseType_t xReturn; /* THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION. It can also be * called from a critical section within an ISR. */ /* The event list is sorted in priority order, so the first in the list can * be removed as it is known to be the highest priority. Remove the TCB from * the delayed list, and add it to the ready list. * * If an event is for a queue that is locked then this function will never * get called - the lock count on the queue will get modified instead. This * means exclusive access to the event list is guaranteed here. * * This function assumes that a check has already been made to ensure that * pxEventList is not empty. */ pxUnblockedTCB = listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ configASSERT( pxUnblockedTCB ); listREMOVE_ITEM( &( pxUnblockedTCB->xEventListItem ) ); if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) { listREMOVE_ITEM( &( pxUnblockedTCB->xStateListItem ) ); prvAddTaskToReadyList( pxUnblockedTCB ); #if ( configUSE_TICKLESS_IDLE != 0 ) { /* If a task is blocked on a kernel object then xNextTaskUnblockTime * might be set to the blocked task's time out time. If the task is * unblocked for a reason other than a timeout xNextTaskUnblockTime is * normally left unchanged, because it is automatically reset to a new * value when the tick count equals xNextTaskUnblockTime. However if * tickless idling is used it might be more important to enter sleep mode * at the earliest possible time - so reset xNextTaskUnblockTime here to * ensure it is updated at the earliest possible time. */ prvResetNextTaskUnblockTime(); } #endif } else { /* The delayed and ready lists cannot be accessed, so hold this task * pending until the scheduler is resumed. */ listINSERT_END( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) ); } if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) { /* Return true if the task removed from the event list has a higher * priority than the calling task. This allows the calling task to know if * it should force a context switch now. */ xReturn = pdTRUE; /* Mark that a yield is pending in case the user is not using the * "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */ xYieldPending = pdTRUE; } else { xReturn = pdFALSE; } return xReturn; } /*-----------------------------------------------------------*/ void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) { TCB_t * pxUnblockedTCB; /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by * the event flags implementation. */ configASSERT( uxSchedulerSuspended != pdFALSE ); /* Store the new item value in the event list. */ listSET_LIST_ITEM_VALUE( pxEventListItem, xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE ); /* Remove the event list form the event flag. Interrupts do not access * event flags. */ pxUnblockedTCB = listGET_LIST_ITEM_OWNER( pxEventListItem ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ configASSERT( pxUnblockedTCB ); listREMOVE_ITEM( pxEventListItem ); #if ( configUSE_TICKLESS_IDLE != 0 ) { /* If a task is blocked on a kernel object then xNextTaskUnblockTime * might be set to the blocked task's time out time. If the task is * unblocked for a reason other than a timeout xNextTaskUnblockTime is * normally left unchanged, because it is automatically reset to a new * value when the tick count equals xNextTaskUnblockTime. However if * tickless idling is used it might be more important to enter sleep mode * at the earliest possible time - so reset xNextTaskUnblockTime here to * ensure it is updated at the earliest possible time. */ prvResetNextTaskUnblockTime(); } #endif /* Remove the task from the delayed list and add it to the ready list. The * scheduler is suspended so interrupts will not be accessing the ready * lists. */ listREMOVE_ITEM( &( pxUnblockedTCB->xStateListItem ) ); prvAddTaskToReadyList( pxUnblockedTCB ); if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) { /* The unblocked task has a priority above that of the calling task, so * a context switch is required. This function is called with the * scheduler suspended so xYieldPending is set so the context switch * occurs immediately that the scheduler is resumed (unsuspended). */ xYieldPending = pdTRUE; } } /*-----------------------------------------------------------*/ void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) { configASSERT( pxTimeOut ); taskENTER_CRITICAL(); { pxTimeOut->xOverflowCount = xNumOfOverflows; pxTimeOut->xTimeOnEntering = xTickCount; } taskEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) { /* For internal use only as it does not use a critical section. */ pxTimeOut->xOverflowCount = xNumOfOverflows; pxTimeOut->xTimeOnEntering = xTickCount; } /*-----------------------------------------------------------*/ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) { BaseType_t xReturn; configASSERT( pxTimeOut ); configASSERT( pxTicksToWait ); taskENTER_CRITICAL(); { /* Minor optimisation. The tick count cannot change in this block. */ const TickType_t xConstTickCount = xTickCount; const TickType_t xElapsedTime = xConstTickCount - pxTimeOut->xTimeOnEntering; #if ( INCLUDE_xTaskAbortDelay == 1 ) if( pxCurrentTCB->ucDelayAborted != ( uint8_t ) pdFALSE ) { /* The delay was aborted, which is not the same as a time out, * but has the same result. */ pxCurrentTCB->ucDelayAborted = pdFALSE; xReturn = pdTRUE; } else #endif #if ( INCLUDE_vTaskSuspend == 1 ) if( *pxTicksToWait == portMAX_DELAY ) { /* If INCLUDE_vTaskSuspend is set to 1 and the block time * specified is the maximum block time then the task should block * indefinitely, and therefore never time out. */ xReturn = pdFALSE; } else #endif if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xConstTickCount >= pxTimeOut->xTimeOnEntering ) ) /*lint !e525 Indentation preferred as is to make code within pre-processor directives clearer. */ { /* The tick count is greater than the time at which * vTaskSetTimeout() was called, but has also overflowed since * vTaskSetTimeOut() was called. It must have wrapped all the way * around and gone past again. This passed since vTaskSetTimeout() * was called. */ xReturn = pdTRUE; *pxTicksToWait = ( TickType_t ) 0; } else if( xElapsedTime < *pxTicksToWait ) /*lint !e961 Explicit casting is only redundant with some compilers, whereas others require it to prevent integer conversion errors. */ { /* Not a genuine timeout. Adjust parameters for time remaining. */ *pxTicksToWait -= xElapsedTime; vTaskInternalSetTimeOutState( pxTimeOut ); xReturn = pdFALSE; } else { *pxTicksToWait = ( TickType_t ) 0; xReturn = pdTRUE; } } taskEXIT_CRITICAL(); return xReturn; } /*-----------------------------------------------------------*/ void vTaskMissedYield( void ) { xYieldPending = pdTRUE; } /*-----------------------------------------------------------*/ #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) { UBaseType_t uxReturn; TCB_t const * pxTCB; if( xTask != NULL ) { pxTCB = xTask; uxReturn = pxTCB->uxTaskNumber; } else { uxReturn = 0U; } return uxReturn; } #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ #if ( configUSE_TRACE_FACILITY == 1 ) void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle ) { TCB_t * pxTCB; if( xTask != NULL ) { pxTCB = xTask; pxTCB->uxTaskNumber = uxHandle; } } #endif /* configUSE_TRACE_FACILITY */ /* * ----------------------------------------------------------- * The Idle task. * ---------------------------------------------------------- * * The portTASK_FUNCTION() macro is used to allow port/compiler specific * language extensions. The equivalent prototype for this function is: * * void prvIdleTask( void *pvParameters ); * */ static portTASK_FUNCTION( prvIdleTask, pvParameters ) { /* Stop warnings. */ ( void ) pvParameters; /** THIS IS THE RTOS IDLE TASK - WHICH IS CREATED AUTOMATICALLY WHEN THE * SCHEDULER IS STARTED. **/ /* In case a task that has a secure context deletes itself, in which case * the idle task is responsible for deleting the task's secure context, if * any. */ portALLOCATE_SECURE_CONTEXT( configMINIMAL_SECURE_STACK_SIZE ); for( ; ; ) { /* See if any tasks have deleted themselves - if so then the idle task * is responsible for freeing the deleted task's TCB and stack. */ prvCheckTasksWaitingTermination(); #if ( configUSE_PREEMPTION == 0 ) { /* If we are not using preemption we keep forcing a task switch to * see if any other task has become available. If we are using * preemption we don't need to do this as any task becoming available * will automatically get the processor anyway. */ taskYIELD(); } #endif /* configUSE_PREEMPTION */ #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) { /* When using preemption tasks of equal priority will be * timesliced. If a task that is sharing the idle priority is ready * to run then the idle task should yield before the end of the * timeslice. * * A critical region is not required here as we are just reading from * the list, and an occasional incorrect value will not matter. If * the ready list at the idle priority contains more than one task * then a task other than the idle task is ready to execute. */ if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) 1 ) { taskYIELD(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */ #if ( configUSE_IDLE_HOOK == 1 ) { extern void vApplicationIdleHook( void ); /* Call the user defined function from within the idle task. This * allows the application designer to add background functionality * without the overhead of a separate task. * NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, * CALL A FUNCTION THAT MIGHT BLOCK. */ vApplicationIdleHook(); } #endif /* configUSE_IDLE_HOOK */ /* This conditional compilation should use inequality to 0, not equality * to 1. This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when * user defined low power mode implementations require * configUSE_TICKLESS_IDLE to be set to a value other than 1. */ #if ( configUSE_TICKLESS_IDLE != 0 ) { TickType_t xExpectedIdleTime; /* It is not desirable to suspend then resume the scheduler on * each iteration of the idle task. Therefore, a preliminary * test of the expected idle time is performed without the * scheduler suspended. The result here is not necessarily * valid. */ xExpectedIdleTime = prvGetExpectedIdleTime(); if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) { vTaskSuspendAll(); { /* Now the scheduler is suspended, the expected idle * time can be sampled again, and this time its value can * be used. */ configASSERT( xNextTaskUnblockTime >= xTickCount ); xExpectedIdleTime = prvGetExpectedIdleTime(); /* Define the following macro to set xExpectedIdleTime to 0 * if the application does not want * portSUPPRESS_TICKS_AND_SLEEP() to be called. */ configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( xExpectedIdleTime ); if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) { traceLOW_POWER_IDLE_BEGIN(); portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ); traceLOW_POWER_IDLE_END(); } else { mtCOVERAGE_TEST_MARKER(); } } ( void ) xTaskResumeAll(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* configUSE_TICKLESS_IDLE */ } } /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE != 0 ) eSleepModeStatus eTaskConfirmSleepModeStatus( void ) { #if ( INCLUDE_vTaskSuspend == 1 ) /* The idle task exists in addition to the application tasks. */ const UBaseType_t uxNonApplicationTasks = 1; #endif /* INCLUDE_vTaskSuspend */ eSleepModeStatus eReturn = eStandardSleep; /* This function must be called from a critical section. */ if( listCURRENT_LIST_LENGTH( &xPendingReadyList ) != 0 ) { /* A task was made ready while the scheduler was suspended. */ eReturn = eAbortSleep; } else if( xYieldPending != pdFALSE ) { /* A yield was pended while the scheduler was suspended. */ eReturn = eAbortSleep; } else if( xPendedTicks != 0 ) { /* A tick interrupt has already occurred but was held pending * because the scheduler is suspended. */ eReturn = eAbortSleep; } #if ( INCLUDE_vTaskSuspend == 1 ) else if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == ( uxCurrentNumberOfTasks - uxNonApplicationTasks ) ) { /* If all the tasks are in the suspended list (which might mean they * have an infinite block time rather than actually being suspended) * then it is safe to turn all clocks off and just wait for external * interrupts. */ eReturn = eNoTasksWaitingTimeout; } #endif /* INCLUDE_vTaskSuspend */ else { mtCOVERAGE_TEST_MARKER(); } return eReturn; } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void * pvValue ) { TCB_t * pxTCB; if( ( xIndex >= 0 ) && ( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) ) { pxTCB = prvGetTCBFromHandle( xTaskToSet ); configASSERT( pxTCB != NULL ); pxTCB->pvThreadLocalStoragePointers[ xIndex ] = pvValue; } } #endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */ /*-----------------------------------------------------------*/ #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) void * pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) { void * pvReturn = NULL; TCB_t * pxTCB; if( ( xIndex >= 0 ) && ( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) ) { pxTCB = prvGetTCBFromHandle( xTaskToQuery ); pvReturn = pxTCB->pvThreadLocalStoragePointers[ xIndex ]; } else { pvReturn = NULL; } return pvReturn; } #endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */ /*-----------------------------------------------------------*/ #if ( portUSING_MPU_WRAPPERS == 1 ) void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, const MemoryRegion_t * const xRegions ) { TCB_t * pxTCB; /* If null is passed in here then we are modifying the MPU settings of * the calling task. */ pxTCB = prvGetTCBFromHandle( xTaskToModify ); vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 ); } #endif /* portUSING_MPU_WRAPPERS */ /*-----------------------------------------------------------*/ static void prvInitialiseTaskLists( void ) { UBaseType_t uxPriority; for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ ) { vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) ); } vListInitialise( &xDelayedTaskList1 ); vListInitialise( &xDelayedTaskList2 ); vListInitialise( &xPendingReadyList ); #if ( INCLUDE_vTaskDelete == 1 ) { vListInitialise( &xTasksWaitingTermination ); } #endif /* INCLUDE_vTaskDelete */ #if ( INCLUDE_vTaskSuspend == 1 ) { vListInitialise( &xSuspendedTaskList ); } #endif /* INCLUDE_vTaskSuspend */ /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList * using list2. */ pxDelayedTaskList = &xDelayedTaskList1; pxOverflowDelayedTaskList = &xDelayedTaskList2; } /*-----------------------------------------------------------*/ static void prvCheckTasksWaitingTermination( void ) { /** THIS FUNCTION IS CALLED FROM THE RTOS IDLE TASK **/ #if ( INCLUDE_vTaskDelete == 1 ) { TCB_t * pxTCB; /* uxDeletedTasksWaitingCleanUp is used to prevent taskENTER_CRITICAL() * being called too often in the idle task. */ while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U ) { taskENTER_CRITICAL(); { pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); --uxCurrentNumberOfTasks; --uxDeletedTasksWaitingCleanUp; } taskEXIT_CRITICAL(); prvDeleteTCB( pxTCB ); } } #endif /* INCLUDE_vTaskDelete */ } /*-----------------------------------------------------------*/ #if ( configUSE_TRACE_FACILITY == 1 ) void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t * pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) { TCB_t * pxTCB; /* xTask is NULL then get the state of the calling task. */ pxTCB = prvGetTCBFromHandle( xTask ); pxTaskStatus->xHandle = ( TaskHandle_t ) pxTCB; pxTaskStatus->pcTaskName = ( const char * ) &( pxTCB->pcTaskName[ 0 ] ); pxTaskStatus->uxCurrentPriority = pxTCB->uxPriority; pxTaskStatus->pxStackBase = pxTCB->pxStack; #if ( ( portSTACK_GROWTH > 0 ) && ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) pxTaskStatus->pxTopOfStack = pxTCB->pxTopOfStack; pxTaskStatus->pxEndOfStack = pxTCB->pxEndOfStack; #endif pxTaskStatus->xTaskNumber = pxTCB->uxTCBNumber; #if ( configUSE_MUTEXES == 1 ) { pxTaskStatus->uxBasePriority = pxTCB->uxBasePriority; } #else { pxTaskStatus->uxBasePriority = 0; } #endif #if ( configGENERATE_RUN_TIME_STATS == 1 ) { pxTaskStatus->ulRunTimeCounter = pxTCB->ulRunTimeCounter; } #else { pxTaskStatus->ulRunTimeCounter = ( configRUN_TIME_COUNTER_TYPE ) 0; } #endif /* Obtaining the task state is a little fiddly, so is only done if the * value of eState passed into this function is eInvalid - otherwise the * state is just set to whatever is passed in. */ if( eState != eInvalid ) { if( pxTCB == pxCurrentTCB ) { pxTaskStatus->eCurrentState = eRunning; } else { pxTaskStatus->eCurrentState = eState; #if ( INCLUDE_vTaskSuspend == 1 ) { /* If the task is in the suspended list then there is a * chance it is actually just blocked indefinitely - so really * it should be reported as being in the Blocked state. */ if( eState == eSuspended ) { vTaskSuspendAll(); { if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) { pxTaskStatus->eCurrentState = eBlocked; } } ( void ) xTaskResumeAll(); } } #endif /* INCLUDE_vTaskSuspend */ } } else { pxTaskStatus->eCurrentState = eTaskGetState( pxTCB ); } /* Obtaining the stack space takes some time, so the xGetFreeStackSpace * parameter is provided to allow it to be skipped. */ if( xGetFreeStackSpace != pdFALSE ) { #if ( portSTACK_GROWTH > 0 ) { pxTaskStatus->usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxTCB->pxEndOfStack ); } #else { pxTaskStatus->usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxTCB->pxStack ); } #endif } else { pxTaskStatus->usStackHighWaterMark = 0; } } #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ #if ( configUSE_TRACE_FACILITY == 1 ) static UBaseType_t prvListTasksWithinSingleList( TaskStatus_t * pxTaskStatusArray, List_t * pxList, eTaskState eState ) { configLIST_VOLATILE TCB_t * pxNextTCB; configLIST_VOLATILE TCB_t * pxFirstTCB; UBaseType_t uxTask = 0; if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) { listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ /* Populate an TaskStatus_t structure within the * pxTaskStatusArray array for each task that is referenced from * pxList. See the definition of TaskStatus_t in task.h for the * meaning of each TaskStatus_t structure member. */ do { listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ vTaskGetInfo( ( TaskHandle_t ) pxNextTCB, &( pxTaskStatusArray[ uxTask ] ), pdTRUE, eState ); uxTask++; } while( pxNextTCB != pxFirstTCB ); } else { mtCOVERAGE_TEST_MARKER(); } return uxTask; } #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ #if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) { uint32_t ulCount = 0U; while( *pucStackByte == ( uint8_t ) tskSTACK_FILL_BYTE ) { pucStackByte -= portSTACK_GROWTH; ulCount++; } ulCount /= ( uint32_t ) sizeof( StackType_t ); /*lint !e961 Casting is not redundant on smaller architectures. */ return ( configSTACK_DEPTH_TYPE ) ulCount; } #endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) /* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the * same except for their return type. Using configSTACK_DEPTH_TYPE allows the * user to determine the return type. It gets around the problem of the value * overflowing on 8-bit types without breaking backward compatibility for * applications that expect an 8-bit return type. */ configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) { TCB_t * pxTCB; uint8_t * pucEndOfStack; configSTACK_DEPTH_TYPE uxReturn; /* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are * the same except for their return type. Using configSTACK_DEPTH_TYPE * allows the user to determine the return type. It gets around the * problem of the value overflowing on 8-bit types without breaking * backward compatibility for applications that expect an 8-bit return * type. */ pxTCB = prvGetTCBFromHandle( xTask ); #if portSTACK_GROWTH < 0 { pucEndOfStack = ( uint8_t * ) pxTCB->pxStack; } #else { pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack; } #endif uxReturn = prvTaskCheckFreeStackSpace( pucEndOfStack ); return uxReturn; } #endif /* INCLUDE_uxTaskGetStackHighWaterMark2 */ /*-----------------------------------------------------------*/ #if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) { TCB_t * pxTCB; uint8_t * pucEndOfStack; UBaseType_t uxReturn; pxTCB = prvGetTCBFromHandle( xTask ); #if portSTACK_GROWTH < 0 { pucEndOfStack = ( uint8_t * ) pxTCB->pxStack; } #else { pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack; } #endif uxReturn = ( UBaseType_t ) prvTaskCheckFreeStackSpace( pucEndOfStack ); return uxReturn; } #endif /* INCLUDE_uxTaskGetStackHighWaterMark */ /*-----------------------------------------------------------*/ #if ( INCLUDE_vTaskDelete == 1 ) static void prvDeleteTCB( TCB_t * pxTCB ) { /* This call is required specifically for the TriCore port. It must be * above the vPortFree() calls. The call is also used by ports/demos that * want to allocate and clean RAM statically. */ portCLEAN_UP_TCB( pxTCB ); #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) { /* Free up the memory allocated for the task's TLS Block. */ configDEINIT_TLS_BLOCK( pxCurrentTCB->xTLSBlock ); } #endif #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) { /* The task can only have been allocated dynamically - free both * the stack and TCB. */ vPortFreeStack( pxTCB->pxStack ); vPortFree( pxTCB ); } #elif ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ { /* The task could have been allocated statically or dynamically, so * check what was statically allocated before trying to free the * memory. */ if( pxTCB->ucStaticallyAllocated == tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ) { /* Both the stack and TCB were allocated dynamically, so both * must be freed. */ vPortFreeStack( pxTCB->pxStack ); vPortFree( pxTCB ); } else if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY ) { /* Only the stack was statically allocated, so the TCB is the * only memory that must be freed. */ vPortFree( pxTCB ); } else { /* Neither the stack nor the TCB were allocated dynamically, so * nothing needs to be freed. */ configASSERT( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB ); mtCOVERAGE_TEST_MARKER(); } } #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ } #endif /* INCLUDE_vTaskDelete */ /*-----------------------------------------------------------*/ static void prvResetNextTaskUnblockTime( void ) { if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) { /* The new current delayed list is empty. Set xNextTaskUnblockTime to * the maximum possible value so it is extremely unlikely that the * if( xTickCount >= xNextTaskUnblockTime ) test will pass until * there is an item in the delayed list. */ xNextTaskUnblockTime = portMAX_DELAY; } else { /* The new current delayed list is not empty, get the value of * the item at the head of the delayed list. This is the time at * which the task at the head of the delayed list should be removed * from the Blocked state. */ xNextTaskUnblockTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxDelayedTaskList ); } } /*-----------------------------------------------------------*/ #if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) TaskHandle_t xTaskGetCurrentTaskHandle( void ) { TaskHandle_t xReturn; /* A critical section is not required as this is not called from * an interrupt and the current TCB will always be the same for any * individual execution thread. */ xReturn = pxCurrentTCB; return xReturn; } #endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) BaseType_t xTaskGetSchedulerState( void ) { BaseType_t xReturn; if( xSchedulerRunning == pdFALSE ) { xReturn = taskSCHEDULER_NOT_STARTED; } else { if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) { xReturn = taskSCHEDULER_RUNNING; } else { xReturn = taskSCHEDULER_SUSPENDED; } } return xReturn; } #endif /* ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( configUSE_MUTEXES == 1 ) BaseType_t xTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) { TCB_t * const pxMutexHolderTCB = pxMutexHolder; BaseType_t xReturn = pdFALSE; /* If the mutex was given back by an interrupt while the queue was * locked then the mutex holder might now be NULL. _RB_ Is this still * needed as interrupts can no longer use mutexes? */ if( pxMutexHolder != NULL ) { /* If the holder of the mutex has a priority below the priority of * the task attempting to obtain the mutex then it will temporarily * inherit the priority of the task attempting to obtain the mutex. */ if( pxMutexHolderTCB->uxPriority < pxCurrentTCB->uxPriority ) { /* Adjust the mutex holder state to account for its new * priority. Only reset the event list item value if the value is * not being used for anything else. */ if( ( listGET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) { listSET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ } else { mtCOVERAGE_TEST_MARKER(); } /* If the task being modified is in the ready state it will need * to be moved into a new list. */ if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxMutexHolderTCB->uxPriority ] ), &( pxMutexHolderTCB->xStateListItem ) ) != pdFALSE ) { if( uxListRemove( &( pxMutexHolderTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) { /* It is known that the task is in its ready list so * there is no need to check again and the port level * reset macro can be called directly. */ portRESET_READY_PRIORITY( pxMutexHolderTCB->uxPriority, uxTopReadyPriority ); } else { mtCOVERAGE_TEST_MARKER(); } /* Inherit the priority before being moved into the new list. */ pxMutexHolderTCB->uxPriority = pxCurrentTCB->uxPriority; prvAddTaskToReadyList( pxMutexHolderTCB ); } else { /* Just inherit the priority. */ pxMutexHolderTCB->uxPriority = pxCurrentTCB->uxPriority; } traceTASK_PRIORITY_INHERIT( pxMutexHolderTCB, pxCurrentTCB->uxPriority ); /* Inheritance occurred. */ xReturn = pdTRUE; } else { if( pxMutexHolderTCB->uxBasePriority < pxCurrentTCB->uxPriority ) { /* The base priority of the mutex holder is lower than the * priority of the task attempting to take the mutex, but the * current priority of the mutex holder is not lower than the * priority of the task attempting to take the mutex. * Therefore the mutex holder must have already inherited a * priority, but inheritance would have occurred if that had * not been the case. */ xReturn = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } } else { mtCOVERAGE_TEST_MARKER(); } return xReturn; } #endif /* configUSE_MUTEXES */ /*-----------------------------------------------------------*/ #if ( configUSE_MUTEXES == 1 ) BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) { TCB_t * const pxTCB = pxMutexHolder; BaseType_t xReturn = pdFALSE; if( pxMutexHolder != NULL ) { /* A task can only have an inherited priority if it holds the mutex. * If the mutex is held by a task then it cannot be given from an * interrupt, and if a mutex is given by the holding task then it must * be the running state task. */ configASSERT( pxTCB == pxCurrentTCB ); configASSERT( pxTCB->uxMutexesHeld ); ( pxTCB->uxMutexesHeld )--; /* Has the holder of the mutex inherited the priority of another * task? */ if( pxTCB->uxPriority != pxTCB->uxBasePriority ) { /* Only disinherit if no other mutexes are held. */ if( pxTCB->uxMutexesHeld == ( UBaseType_t ) 0 ) { /* A task can only have an inherited priority if it holds * the mutex. If the mutex is held by a task then it cannot be * given from an interrupt, and if a mutex is given by the * holding task then it must be the running state task. Remove * the holding task from the ready list. */ if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) { portRESET_READY_PRIORITY( pxTCB->uxPriority, uxTopReadyPriority ); } else { mtCOVERAGE_TEST_MARKER(); } /* Disinherit the priority before adding the task into the * new ready list. */ traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority ); pxTCB->uxPriority = pxTCB->uxBasePriority; /* Reset the event list item value. It cannot be in use for * any other purpose if this task is running, and it must be * running to give back the mutex. */ listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ prvAddTaskToReadyList( pxTCB ); /* Return true to indicate that a context switch is required. * This is only actually required in the corner case whereby * multiple mutexes were held and the mutexes were given back * in an order different to that in which they were taken. * If a context switch did not occur when the first mutex was * returned, even if a task was waiting on it, then a context * switch should occur when the last mutex is returned whether * a task is waiting on it or not. */ xReturn = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } return xReturn; } #endif /* configUSE_MUTEXES */ /*-----------------------------------------------------------*/ #if ( configUSE_MUTEXES == 1 ) void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder, UBaseType_t uxHighestPriorityWaitingTask ) { TCB_t * const pxTCB = pxMutexHolder; UBaseType_t uxPriorityUsedOnEntry, uxPriorityToUse; const UBaseType_t uxOnlyOneMutexHeld = ( UBaseType_t ) 1; if( pxMutexHolder != NULL ) { /* If pxMutexHolder is not NULL then the holder must hold at least * one mutex. */ configASSERT( pxTCB->uxMutexesHeld ); /* Determine the priority to which the priority of the task that * holds the mutex should be set. This will be the greater of the * holding task's base priority and the priority of the highest * priority task that is waiting to obtain the mutex. */ if( pxTCB->uxBasePriority < uxHighestPriorityWaitingTask ) { uxPriorityToUse = uxHighestPriorityWaitingTask; } else { uxPriorityToUse = pxTCB->uxBasePriority; } /* Does the priority need to change? */ if( pxTCB->uxPriority != uxPriorityToUse ) { /* Only disinherit if no other mutexes are held. This is a * simplification in the priority inheritance implementation. If * the task that holds the mutex is also holding other mutexes then * the other mutexes may have caused the priority inheritance. */ if( pxTCB->uxMutexesHeld == uxOnlyOneMutexHeld ) { /* If a task has timed out because it already holds the * mutex it was trying to obtain then it cannot of inherited * its own priority. */ configASSERT( pxTCB != pxCurrentTCB ); /* Disinherit the priority, remembering the previous * priority to facilitate determining the subject task's * state. */ traceTASK_PRIORITY_DISINHERIT( pxTCB, uxPriorityToUse ); uxPriorityUsedOnEntry = pxTCB->uxPriority; pxTCB->uxPriority = uxPriorityToUse; /* Only reset the event list item value if the value is not * being used for anything else. */ if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) { listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriorityToUse ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ } else { mtCOVERAGE_TEST_MARKER(); } /* If the running task is not the task that holds the mutex * then the task that holds the mutex could be in either the * Ready, Blocked or Suspended states. Only remove the task * from its current state list if it is in the Ready state as * the task's priority is going to change and there is one * Ready list per priority. */ if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xStateListItem ) ) != pdFALSE ) { if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) { /* It is known that the task is in its ready list so * there is no need to check again and the port level * reset macro can be called directly. */ portRESET_READY_PRIORITY( pxTCB->uxPriority, uxTopReadyPriority ); } else { mtCOVERAGE_TEST_MARKER(); } prvAddTaskToReadyList( pxTCB ); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* configUSE_MUTEXES */ /*-----------------------------------------------------------*/ #if ( portCRITICAL_NESTING_IN_TCB == 1 ) void vTaskEnterCritical( void ) { portDISABLE_INTERRUPTS(); if( xSchedulerRunning != pdFALSE ) { ( pxCurrentTCB->uxCriticalNesting )++; /* 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 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 assert function also uses a * critical section. */ if( pxCurrentTCB->uxCriticalNesting == 1 ) { portASSERT_IF_IN_ISR(); } } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* portCRITICAL_NESTING_IN_TCB */ /*-----------------------------------------------------------*/ #if ( portCRITICAL_NESTING_IN_TCB == 1 ) void vTaskExitCritical( void ) { if( xSchedulerRunning != pdFALSE ) { if( pxCurrentTCB->uxCriticalNesting > 0U ) { ( pxCurrentTCB->uxCriticalNesting )--; if( pxCurrentTCB->uxCriticalNesting == 0U ) { portENABLE_INTERRUPTS(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* portCRITICAL_NESTING_IN_TCB */ /*-----------------------------------------------------------*/ #if ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) static char * prvWriteNameToBuffer( char * pcBuffer, const char * pcTaskName ) { size_t x; /* Start by copying the entire string. */ strcpy( pcBuffer, pcTaskName ); /* Pad the end of the string with spaces to ensure columns line up when * printed out. */ for( x = strlen( pcBuffer ); x < ( size_t ) ( configMAX_TASK_NAME_LEN - 1 ); x++ ) { pcBuffer[ x ] = ' '; } /* Terminate. */ pcBuffer[ x ] = ( char ) 0x00; /* Return the new end of string. */ return &( pcBuffer[ x ] ); } #endif /* ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) */ /*-----------------------------------------------------------*/ #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) void vTaskList( char * pcWriteBuffer ) { TaskStatus_t * pxTaskStatusArray; UBaseType_t uxArraySize, x; char cStatus; /* * PLEASE NOTE: * * This function is provided for convenience only, and is used by many * of the demo applications. Do not consider it to be part of the * scheduler. * * vTaskList() calls uxTaskGetSystemState(), then formats part of the * uxTaskGetSystemState() output into a human readable table that * displays task: names, states, priority, stack usage and task number. * Stack usage specified as the number of unused StackType_t words stack can hold * on top of stack - not the number of bytes. * * vTaskList() has a dependency on the sprintf() C library function that * might bloat the code size, use a lot of stack, and provide different * results on different platforms. An alternative, tiny, third party, * and limited functionality implementation of sprintf() is provided in * many of the FreeRTOS/Demo sub-directories in a file called * printf-stdarg.c (note printf-stdarg.c does not provide a full * snprintf() implementation!). * * It is recommended that production systems call uxTaskGetSystemState() * directly to get access to raw stats data, rather than indirectly * through a call to vTaskList(). */ /* Make sure the write buffer does not contain a string. */ *pcWriteBuffer = ( char ) 0x00; /* Take a snapshot of the number of tasks in case it changes while this * function is executing. */ uxArraySize = uxCurrentNumberOfTasks; /* Allocate an array index for each task. NOTE! if * configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will * equate to NULL. */ pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation allocates a struct that has the alignment requirements of a pointer. */ if( pxTaskStatusArray != NULL ) { /* Generate the (binary) data. */ uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, NULL ); /* Create a human readable table from the binary data. */ for( x = 0; x < uxArraySize; x++ ) { switch( pxTaskStatusArray[ x ].eCurrentState ) { case eRunning: cStatus = tskRUNNING_CHAR; break; case eReady: cStatus = tskREADY_CHAR; break; case eBlocked: cStatus = tskBLOCKED_CHAR; break; case eSuspended: cStatus = tskSUSPENDED_CHAR; break; case eDeleted: cStatus = tskDELETED_CHAR; break; case eInvalid: /* Fall through. */ default: /* Should not get here, but it is included * to prevent static checking errors. */ cStatus = ( char ) 0x00; break; } /* Write the task name to the string, padding with spaces so it * can be printed in tabular form more easily. */ pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName ); /* Write the rest of the string. */ sprintf( pcWriteBuffer, "\t%c\t%u\t%u\t%u\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber ); /*lint !e586 sprintf() allowed as this is compiled with many compilers and this is a utility function only - not part of the core kernel implementation. */ pcWriteBuffer += strlen( pcWriteBuffer ); /*lint !e9016 Pointer arithmetic ok on char pointers especially as in this case where it best denotes the intent of the code. */ } /* Free the array again. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION * is 0 then vPortFree() will be #defined to nothing. */ vPortFree( pxTaskStatusArray ); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */ /*----------------------------------------------------------*/ #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void vTaskGetRunTimeStats( char * pcWriteBuffer ) { TaskStatus_t * pxTaskStatusArray; UBaseType_t uxArraySize, x; configRUN_TIME_COUNTER_TYPE ulTotalTime, ulStatsAsPercentage; /* * PLEASE NOTE: * * This function is provided for convenience only, and is used by many * of the demo applications. Do not consider it to be part of the * scheduler. * * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part * of the uxTaskGetSystemState() output into a human readable table that * displays the amount of time each task has spent in the Running state * in both absolute and percentage terms. * * vTaskGetRunTimeStats() has a dependency on the sprintf() C library * function that might bloat the code size, use a lot of stack, and * provide different results on different platforms. An alternative, * tiny, third party, and limited functionality implementation of * sprintf() is provided in many of the FreeRTOS/Demo sub-directories in * a file called printf-stdarg.c (note printf-stdarg.c does not provide * a full snprintf() implementation!). * * It is recommended that production systems call uxTaskGetSystemState() * directly to get access to raw stats data, rather than indirectly * through a call to vTaskGetRunTimeStats(). */ /* Make sure the write buffer does not contain a string. */ *pcWriteBuffer = ( char ) 0x00; /* Take a snapshot of the number of tasks in case it changes while this * function is executing. */ uxArraySize = uxCurrentNumberOfTasks; /* Allocate an array index for each task. NOTE! If * configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will * equate to NULL. */ pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation allocates a struct that has the alignment requirements of a pointer. */ if( pxTaskStatusArray != NULL ) { /* Generate the (binary) data. */ uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalTime ); /* For percentage calculations. */ ulTotalTime /= 100UL; /* Avoid divide by zero errors. */ if( ulTotalTime > 0UL ) { /* Create a human readable table from the binary data. */ for( x = 0; x < uxArraySize; x++ ) { /* What percentage of the total run time has the task used? * This will always be rounded down to the nearest integer. * ulTotalRunTime has already been divided by 100. */ ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime; /* Write the task name to the string, padding with * spaces so it can be printed in tabular form more * easily. */ pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName ); if( ulStatsAsPercentage > 0UL ) { #ifdef portLU_PRINTF_SPECIFIER_REQUIRED { sprintf( pcWriteBuffer, "\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage ); } #else { /* sizeof( int ) == sizeof( long ) so a smaller * printf() library can be used. */ sprintf( pcWriteBuffer, "\t%u\t\t%u%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage ); /*lint !e586 sprintf() allowed as this is compiled with many compilers and this is a utility function only - not part of the core kernel implementation. */ } #endif } else { /* If the percentage is zero here then the task has * consumed less than 1% of the total run time. */ #ifdef portLU_PRINTF_SPECIFIER_REQUIRED { sprintf( pcWriteBuffer, "\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].ulRunTimeCounter ); } #else { /* sizeof( int ) == sizeof( long ) so a smaller * printf() library can be used. */ sprintf( pcWriteBuffer, "\t%u\t\t<1%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter ); /*lint !e586 sprintf() allowed as this is compiled with many compilers and this is a utility function only - not part of the core kernel implementation. */ } #endif } pcWriteBuffer += strlen( pcWriteBuffer ); /*lint !e9016 Pointer arithmetic ok on char pointers especially as in this case where it best denotes the intent of the code. */ } } else { mtCOVERAGE_TEST_MARKER(); } /* Free the array again. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION * is 0 then vPortFree() will be #defined to nothing. */ vPortFree( pxTaskStatusArray ); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */ /*-----------------------------------------------------------*/ TickType_t uxTaskResetEventItemValue( void ) { TickType_t uxReturn; uxReturn = listGET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ) ); /* Reset the event list item to its normal value - so it can be used with * queues and semaphores. */ listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ return uxReturn; } /*-----------------------------------------------------------*/ #if ( configUSE_MUTEXES == 1 ) TaskHandle_t pvTaskIncrementMutexHeldCount( void ) { /* If xSemaphoreCreateMutex() is called before any tasks have been created * then pxCurrentTCB will be NULL. */ if( pxCurrentTCB != NULL ) { ( pxCurrentTCB->uxMutexesHeld )++; } return pxCurrentTCB; } #endif /* configUSE_MUTEXES */ /*-----------------------------------------------------------*/ #if ( configUSE_TASK_NOTIFICATIONS == 1 ) uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWait, BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) { uint32_t ulReturn; configASSERT( uxIndexToWait < configTASK_NOTIFICATION_ARRAY_ENTRIES ); taskENTER_CRITICAL(); { /* Only block if the notification count is not already non-zero. */ if( pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] == 0UL ) { /* Mark this task as waiting for a notification. */ pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskWAITING_NOTIFICATION; if( xTicksToWait > ( TickType_t ) 0 ) { prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); traceTASK_NOTIFY_TAKE_BLOCK( uxIndexToWait ); /* All ports are written to allow a yield in a critical * section (some will yield immediately, others wait until the * critical section exits) - but it is not something that * application code should ever do. */ portYIELD_WITHIN_API(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } taskEXIT_CRITICAL(); taskENTER_CRITICAL(); { traceTASK_NOTIFY_TAKE( uxIndexToWait ); ulReturn = pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ]; if( ulReturn != 0UL ) { if( xClearCountOnExit != pdFALSE ) { pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] = 0UL; } else { pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] = ulReturn - ( uint32_t ) 1; } } else { mtCOVERAGE_TEST_MARKER(); } pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskNOT_WAITING_NOTIFICATION; } taskEXIT_CRITICAL(); return ulReturn; } #endif /* configUSE_TASK_NOTIFICATIONS */ /*-----------------------------------------------------------*/ #if ( configUSE_TASK_NOTIFICATIONS == 1 ) BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWait, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t * pulNotificationValue, TickType_t xTicksToWait ) { BaseType_t xReturn; configASSERT( uxIndexToWait < configTASK_NOTIFICATION_ARRAY_ENTRIES ); taskENTER_CRITICAL(); { /* Only block if a notification is not already pending. */ if( pxCurrentTCB->ucNotifyState[ uxIndexToWait ] != taskNOTIFICATION_RECEIVED ) { /* Clear bits in the task's notification value as bits may get * set by the notifying task or interrupt. This can be used to * clear the value to zero. */ pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] &= ~ulBitsToClearOnEntry; /* Mark this task as waiting for a notification. */ pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskWAITING_NOTIFICATION; if( xTicksToWait > ( TickType_t ) 0 ) { prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); traceTASK_NOTIFY_WAIT_BLOCK( uxIndexToWait ); /* All ports are written to allow a yield in a critical * section (some will yield immediately, others wait until the * critical section exits) - but it is not something that * application code should ever do. */ portYIELD_WITHIN_API(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } taskEXIT_CRITICAL(); taskENTER_CRITICAL(); { traceTASK_NOTIFY_WAIT( uxIndexToWait ); if( pulNotificationValue != NULL ) { /* Output the current notification value, which may or may not * have changed. */ *pulNotificationValue = pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ]; } /* If ucNotifyValue is set then either the task never entered the * blocked state (because a notification was already pending) or the * task unblocked because of a notification. Otherwise the task * unblocked because of a timeout. */ if( pxCurrentTCB->ucNotifyState[ uxIndexToWait ] != taskNOTIFICATION_RECEIVED ) { /* A notification was not received. */ xReturn = pdFALSE; } else { /* A notification was already pending or a notification was * received while the task was waiting. */ pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] &= ~ulBitsToClearOnExit; xReturn = pdTRUE; } pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskNOT_WAITING_NOTIFICATION; } taskEXIT_CRITICAL(); return xReturn; } #endif /* configUSE_TASK_NOTIFICATIONS */ /*-----------------------------------------------------------*/ #if ( configUSE_TASK_NOTIFICATIONS == 1 ) BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t * pulPreviousNotificationValue ) { TCB_t * pxTCB; BaseType_t xReturn = pdPASS; uint8_t ucOriginalNotifyState; configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES ); configASSERT( xTaskToNotify ); pxTCB = xTaskToNotify; taskENTER_CRITICAL(); { if( pulPreviousNotificationValue != NULL ) { *pulPreviousNotificationValue = pxTCB->ulNotifiedValue[ uxIndexToNotify ]; } ucOriginalNotifyState = pxTCB->ucNotifyState[ uxIndexToNotify ]; pxTCB->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED; switch( eAction ) { case eSetBits: pxTCB->ulNotifiedValue[ uxIndexToNotify ] |= ulValue; break; case eIncrement: ( pxTCB->ulNotifiedValue[ uxIndexToNotify ] )++; break; case eSetValueWithOverwrite: pxTCB->ulNotifiedValue[ uxIndexToNotify ] = ulValue; break; case eSetValueWithoutOverwrite: if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED ) { pxTCB->ulNotifiedValue[ uxIndexToNotify ] = ulValue; } else { /* The value could not be written to the task. */ xReturn = pdFAIL; } break; case eNoAction: /* The task is being notified without its notify value being * updated. */ break; default: /* Should not get here if all enums are handled. * Artificially force an assert by testing a value the * compiler can't assume is const. */ configASSERT( xTickCount == ( TickType_t ) 0 ); break; } traceTASK_NOTIFY( uxIndexToNotify ); /* If the task is in the blocked state specifically to wait for a * notification then unblock it now. */ if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) { listREMOVE_ITEM( &( pxTCB->xStateListItem ) ); prvAddTaskToReadyList( pxTCB ); /* The task should not have been on an event list. */ configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); #if ( configUSE_TICKLESS_IDLE != 0 ) { /* If a task is blocked waiting for a notification then * xNextTaskUnblockTime might be set to the blocked task's time * out time. If the task is unblocked for a reason other than * a timeout xNextTaskUnblockTime is normally left unchanged, * because it will automatically get reset to a new value when * the tick count equals xNextTaskUnblockTime. However if * tickless idling is used it might be more important to enter * sleep mode at the earliest possible time - so reset * xNextTaskUnblockTime here to ensure it is updated at the * earliest possible time. */ prvResetNextTaskUnblockTime(); } #endif if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) { /* The notified task has a priority above the currently * executing task so a yield is required. */ taskYIELD_IF_USING_PREEMPTION(); } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } taskEXIT_CRITICAL(); return xReturn; } #endif /* configUSE_TASK_NOTIFICATIONS */ /*-----------------------------------------------------------*/ #if ( configUSE_TASK_NOTIFICATIONS == 1 ) BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t * pulPreviousNotificationValue, BaseType_t * pxHigherPriorityTaskWoken ) { TCB_t * pxTCB; uint8_t ucOriginalNotifyState; BaseType_t xReturn = pdPASS; UBaseType_t uxSavedInterruptStatus; configASSERT( xTaskToNotify ); configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES ); /* RTOS ports that support interrupt nesting have the concept of a * maximum system call (or maximum API call) interrupt priority. * Interrupts that are above the maximum system call priority are keep * permanently enabled, even when the RTOS kernel is in a critical section, * but cannot make any calls to FreeRTOS API functions. If configASSERT() * is defined in FreeRTOSConfig.h then * portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion * failure if a FreeRTOS API function is called from an interrupt that has * been assigned a priority above the configured maximum system call * priority. Only FreeRTOS functions that end in FromISR can be called * from interrupts that have been assigned a priority at or (logically) * below the maximum system call interrupt priority. FreeRTOS maintains a * separate interrupt safe API to ensure interrupt entry is as fast and as * simple as possible. More information (albeit Cortex-M specific) is * provided on the following link: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); pxTCB = xTaskToNotify; uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { if( pulPreviousNotificationValue != NULL ) { *pulPreviousNotificationValue = pxTCB->ulNotifiedValue[ uxIndexToNotify ]; } ucOriginalNotifyState = pxTCB->ucNotifyState[ uxIndexToNotify ]; pxTCB->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED; switch( eAction ) { case eSetBits: pxTCB->ulNotifiedValue[ uxIndexToNotify ] |= ulValue; break; case eIncrement: ( pxTCB->ulNotifiedValue[ uxIndexToNotify ] )++; break; case eSetValueWithOverwrite: pxTCB->ulNotifiedValue[ uxIndexToNotify ] = ulValue; break; case eSetValueWithoutOverwrite: if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED ) { pxTCB->ulNotifiedValue[ uxIndexToNotify ] = ulValue; } else { /* The value could not be written to the task. */ xReturn = pdFAIL; } break; case eNoAction: /* The task is being notified without its notify value being * updated. */ break; default: /* Should not get here if all enums are handled. * Artificially force an assert by testing a value the * compiler can't assume is const. */ configASSERT( xTickCount == ( TickType_t ) 0 ); break; } traceTASK_NOTIFY_FROM_ISR( uxIndexToNotify ); /* If the task is in the blocked state specifically to wait for a * notification then unblock it now. */ if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) { /* The task should not have been on an event list. */ configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) { listREMOVE_ITEM( &( pxTCB->xStateListItem ) ); prvAddTaskToReadyList( pxTCB ); } else { /* The delayed and ready lists cannot be accessed, so hold * this task pending until the scheduler is resumed. */ listINSERT_END( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); } if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) { /* The notified task has a priority above the currently * executing task so a yield is required. */ if( pxHigherPriorityTaskWoken != NULL ) { *pxHigherPriorityTaskWoken = pdTRUE; } /* Mark that a yield is pending in case the user is not * using the "xHigherPriorityTaskWoken" parameter to an ISR * safe FreeRTOS function. */ xYieldPending = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } } portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } #endif /* configUSE_TASK_NOTIFICATIONS */ /*-----------------------------------------------------------*/ #if ( configUSE_TASK_NOTIFICATIONS == 1 ) void vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, BaseType_t * pxHigherPriorityTaskWoken ) { TCB_t * pxTCB; uint8_t ucOriginalNotifyState; UBaseType_t uxSavedInterruptStatus; configASSERT( xTaskToNotify ); configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES ); /* RTOS ports that support interrupt nesting have the concept of a * maximum system call (or maximum API call) interrupt priority. * Interrupts that are above the maximum system call priority are keep * permanently enabled, even when the RTOS kernel is in a critical section, * but cannot make any calls to FreeRTOS API functions. If configASSERT() * is defined in FreeRTOSConfig.h then * portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion * failure if a FreeRTOS API function is called from an interrupt that has * been assigned a priority above the configured maximum system call * priority. Only FreeRTOS functions that end in FromISR can be called * from interrupts that have been assigned a priority at or (logically) * below the maximum system call interrupt priority. FreeRTOS maintains a * separate interrupt safe API to ensure interrupt entry is as fast and as * simple as possible. More information (albeit Cortex-M specific) is * provided on the following link: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); pxTCB = xTaskToNotify; uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { ucOriginalNotifyState = pxTCB->ucNotifyState[ uxIndexToNotify ]; pxTCB->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED; /* 'Giving' is equivalent to incrementing a count in a counting * semaphore. */ ( pxTCB->ulNotifiedValue[ uxIndexToNotify ] )++; traceTASK_NOTIFY_GIVE_FROM_ISR( uxIndexToNotify ); /* If the task is in the blocked state specifically to wait for a * notification then unblock it now. */ if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) { /* The task should not have been on an event list. */ configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) { listREMOVE_ITEM( &( pxTCB->xStateListItem ) ); prvAddTaskToReadyList( pxTCB ); } else { /* The delayed and ready lists cannot be accessed, so hold * this task pending until the scheduler is resumed. */ listINSERT_END( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); } if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) { /* The notified task has a priority above the currently * executing task so a yield is required. */ if( pxHigherPriorityTaskWoken != NULL ) { *pxHigherPriorityTaskWoken = pdTRUE; } /* Mark that a yield is pending in case the user is not * using the "xHigherPriorityTaskWoken" parameter in an ISR * safe FreeRTOS function. */ xYieldPending = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } } portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); } #endif /* configUSE_TASK_NOTIFICATIONS */ /*-----------------------------------------------------------*/ #if ( configUSE_TASK_NOTIFICATIONS == 1 ) BaseType_t xTaskGenericNotifyStateClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear ) { TCB_t * pxTCB; BaseType_t xReturn; configASSERT( uxIndexToClear < configTASK_NOTIFICATION_ARRAY_ENTRIES ); /* If null is passed in here then it is the calling task that is having * its notification state cleared. */ pxTCB = prvGetTCBFromHandle( xTask ); taskENTER_CRITICAL(); { if( pxTCB->ucNotifyState[ uxIndexToClear ] == taskNOTIFICATION_RECEIVED ) { pxTCB->ucNotifyState[ uxIndexToClear ] = taskNOT_WAITING_NOTIFICATION; xReturn = pdPASS; } else { xReturn = pdFAIL; } } taskEXIT_CRITICAL(); return xReturn; } #endif /* configUSE_TASK_NOTIFICATIONS */ /*-----------------------------------------------------------*/ #if ( configUSE_TASK_NOTIFICATIONS == 1 ) uint32_t ulTaskGenericNotifyValueClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear ) { TCB_t * pxTCB; uint32_t ulReturn; /* If null is passed in here then it is the calling task that is having * its notification state cleared. */ pxTCB = prvGetTCBFromHandle( xTask ); taskENTER_CRITICAL(); { /* Return the notification as it was before the bits were cleared, * then clear the bit mask. */ ulReturn = pxTCB->ulNotifiedValue[ uxIndexToClear ]; pxTCB->ulNotifiedValue[ uxIndexToClear ] &= ~ulBitsToClear; } taskEXIT_CRITICAL(); return ulReturn; } #endif /* configUSE_TASK_NOTIFICATIONS */ /*-----------------------------------------------------------*/ #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ) { return xIdleTaskHandle->ulRunTimeCounter; } #endif /*-----------------------------------------------------------*/ #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercent( void ) { configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn; ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE(); /* For percentage calculations. */ ulTotalTime /= ( configRUN_TIME_COUNTER_TYPE ) 100; /* Avoid divide by zero errors. */ if( ulTotalTime > ( configRUN_TIME_COUNTER_TYPE ) 0 ) { ulReturn = xIdleTaskHandle->ulRunTimeCounter / ulTotalTime; } else { ulReturn = 0; } return ulReturn; } #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ /*-----------------------------------------------------------*/ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseType_t xCanBlockIndefinitely ) { TickType_t xTimeToWake; const TickType_t xConstTickCount = xTickCount; #if ( INCLUDE_xTaskAbortDelay == 1 ) { /* About to enter a delayed list, so ensure the ucDelayAborted flag is * reset to pdFALSE so it can be detected as having been set to pdTRUE * when the task leaves the Blocked state. */ pxCurrentTCB->ucDelayAborted = pdFALSE; } #endif /* Remove the task from the ready list before adding it to the blocked list * as the same list item is used for both lists. */ if( uxListRemove( &( pxCurrentTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) { /* The current task must be in a ready list, so there is no need to * check, and the port reset macro can be called directly. */ portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); /*lint !e931 pxCurrentTCB cannot change as it is the calling task. pxCurrentTCB->uxPriority and uxTopReadyPriority cannot change as called with scheduler suspended or in a critical section. */ } else { mtCOVERAGE_TEST_MARKER(); } #if ( INCLUDE_vTaskSuspend == 1 ) { if( ( xTicksToWait == portMAX_DELAY ) && ( xCanBlockIndefinitely != pdFALSE ) ) { /* Add the task to the suspended task list instead of a delayed task * list to ensure it is not woken by a timing event. It will block * indefinitely. */ listINSERT_END( &xSuspendedTaskList, &( pxCurrentTCB->xStateListItem ) ); } else { /* Calculate the time at which the task should be woken if the event * does not occur. This may overflow but this doesn't matter, the * kernel will manage it correctly. */ xTimeToWake = xConstTickCount + xTicksToWait; /* The list item will be inserted in wake time order. */ listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake ); if( xTimeToWake < xConstTickCount ) { /* Wake time has overflowed. Place this item in the overflow * list. */ vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); } else { /* The wake time has not overflowed, so the current block list * is used. */ vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); /* If the task entering the blocked state was placed at the * head of the list of blocked tasks then xNextTaskUnblockTime * needs to be updated too. */ if( xTimeToWake < xNextTaskUnblockTime ) { xNextTaskUnblockTime = xTimeToWake; } else { mtCOVERAGE_TEST_MARKER(); } } } } #else /* INCLUDE_vTaskSuspend */ { /* Calculate the time at which the task should be woken if the event * does not occur. This may overflow but this doesn't matter, the kernel * will manage it correctly. */ xTimeToWake = xConstTickCount + xTicksToWait; /* The list item will be inserted in wake time order. */ listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake ); if( xTimeToWake < xConstTickCount ) { /* Wake time has overflowed. Place this item in the overflow list. */ vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); } else { /* The wake time has not overflowed, so the current block list is used. */ vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); /* If the task entering the blocked state was placed at the head of the * list of blocked tasks then xNextTaskUnblockTime needs to be updated * too. */ if( xTimeToWake < xNextTaskUnblockTime ) { xNextTaskUnblockTime = xTimeToWake; } else { mtCOVERAGE_TEST_MARKER(); } } /* Avoid compiler warning when INCLUDE_vTaskSuspend is not 1. */ ( void ) xCanBlockIndefinitely; } #endif /* INCLUDE_vTaskSuspend */ } /* Code below here allows additional code to be inserted into this source file, * especially where access to file scope functions and data is needed (for example * when performing module tests). */ #ifdef FREERTOS_MODULE_TEST #include "tasks_test_access_functions.h" #endif #if ( configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H == 1 ) #include "freertos_tasks_c_additions.h" #ifdef FREERTOS_TASKS_C_ADDITIONS_INIT static void freertos_tasks_c_additions_init( void ) { FREERTOS_TASKS_C_ADDITIONS_INIT(); } #endif #endif /* if ( configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H == 1 ) */ ================================================ FILE: FreeRTOS-comparison/timers.c ================================================ /* * FreeRTOS Kernel V10.5.1 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /* Standard includes. */ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "timers.h" #if ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 0 ) #error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available. #endif /* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified * because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined * for the header files above, but not in this file, in order to generate the * correct privileged Vs unprivileged linkage and placement. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e9021 !e961 !e750. */ /* This entire source file will be skipped if the application is not configured * to include software timer functionality. This #if is closed at the very bottom * of this file. If you want to include software timer functionality then ensure * configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ #if ( configUSE_TIMERS == 1 ) /* Misc definitions. */ #define tmrNO_DELAY ( ( TickType_t ) 0U ) #define tmrMAX_TIME_BEFORE_OVERFLOW ( ( TickType_t ) -1 ) /* The name assigned to the timer service task. This can be overridden by * defining trmTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */ #ifndef configTIMER_SERVICE_TASK_NAME #define configTIMER_SERVICE_TASK_NAME "Tmr Svc" #endif /* Bit definitions used in the ucStatus member of a timer structure. */ #define tmrSTATUS_IS_ACTIVE ( ( uint8_t ) 0x01 ) #define tmrSTATUS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 0x02 ) #define tmrSTATUS_IS_AUTORELOAD ( ( uint8_t ) 0x04 ) /* The definition of the timers themselves. */ typedef struct tmrTimerControl /* The old naming convention is used to prevent breaking kernel aware debuggers. */ { const char * pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */ TickType_t xTimerPeriodInTicks; /*<< How quickly and often the timer expires. */ void * pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */ TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */ #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */ #endif uint8_t ucStatus; /*<< Holds bits to say if the timer was statically allocated or not, and if it is active or not. */ } xTIMER; /* The old xTIMER name is maintained above then typedefed to the new Timer_t * name below to enable the use of older kernel aware debuggers. */ typedef xTIMER Timer_t; /* The definition of messages that can be sent and received on the timer queue. * Two types of message can be queued - messages that manipulate a software timer, * and messages that request the execution of a non-timer related callback. The * two message types are defined in two separate structures, xTimerParametersType * and xCallbackParametersType respectively. */ typedef struct tmrTimerParameters { TickType_t xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */ Timer_t * pxTimer; /*<< The timer to which the command will be applied. */ } TimerParameter_t; typedef struct tmrCallbackParameters { PendedFunction_t pxCallbackFunction; /* << The callback function to execute. */ void * pvParameter1; /* << The value that will be used as the callback functions first parameter. */ uint32_t ulParameter2; /* << The value that will be used as the callback functions second parameter. */ } CallbackParameters_t; /* The structure that contains the two message types, along with an identifier * that is used to determine which message type is valid. */ typedef struct tmrTimerQueueMessage { BaseType_t xMessageID; /*<< The command being sent to the timer service task. */ union { TimerParameter_t xTimerParameters; /* Don't include xCallbackParameters if it is not going to be used as * it makes the structure (and therefore the timer queue) larger. */ #if ( INCLUDE_xTimerPendFunctionCall == 1 ) CallbackParameters_t xCallbackParameters; #endif /* INCLUDE_xTimerPendFunctionCall */ } u; } DaemonTaskMessage_t; /*lint -save -e956 A manual analysis and inspection has been used to determine * which static variables must be declared volatile. */ /* The list in which active timers are stored. Timers are referenced in expire * time order, with the nearest expiry time at the front of the list. Only the * timer service task is allowed to access these lists. * xActiveTimerList1 and xActiveTimerList2 could be at function scope but that * breaks some kernel aware debuggers, and debuggers that reply on removing the * static qualifier. */ PRIVILEGED_DATA static List_t xActiveTimerList1; PRIVILEGED_DATA static List_t xActiveTimerList2; PRIVILEGED_DATA static List_t * pxCurrentTimerList; PRIVILEGED_DATA static List_t * pxOverflowTimerList; /* A queue that is used to send commands to the timer service task. */ PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL; PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL; /*lint -restore */ /*-----------------------------------------------------------*/ /* * Initialise the infrastructure used by the timer service task if it has not * been initialised already. */ static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION; /* * The timer service task (daemon). Timer functionality is controlled by this * task. Other tasks communicate with the timer service task using the * xTimerQueue queue. */ static portTASK_FUNCTION_PROTO( prvTimerTask, pvParameters ) PRIVILEGED_FUNCTION; /* * Called by the timer service task to interpret and process a command it * received on the timer queue. */ static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION; /* * Insert the timer into either xActiveTimerList1, or xActiveTimerList2, * depending on if the expire time causes a timer counter overflow. */ static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) PRIVILEGED_FUNCTION; /* * Reload the specified auto-reload timer. If the reloading is backlogged, * clear the backlog, calling the callback for each additional reload. When * this function returns, the next expiry time is after xTimeNow. */ static void prvReloadTimer( Timer_t * const pxTimer, TickType_t xExpiredTime, const TickType_t xTimeNow ) PRIVILEGED_FUNCTION; /* * An active timer has reached its expire time. Reload the timer if it is an * auto-reload timer, then call its callback. */ static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) PRIVILEGED_FUNCTION; /* * The tick count has overflowed. Switch the timer lists after ensuring the * current timer list does not still reference some timers. */ static void prvSwitchTimerLists( void ) PRIVILEGED_FUNCTION; /* * Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE * if a tick count overflow occurred since prvSampleTimeNow() was last called. */ static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION; /* * If the timer list contains any active timers then return the expire time of * the timer that will expire first and set *pxListWasEmpty to false. If the * timer list does not contain any timers then return 0 and set *pxListWasEmpty * to pdTRUE. */ static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) PRIVILEGED_FUNCTION; /* * If a timer has expired, process it. Otherwise, block the timer service task * until either a timer does expire or a command is received. */ static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty ) PRIVILEGED_FUNCTION; /* * Called after a Timer_t structure has been allocated either statically or * dynamically to fill in the structure's members. */ static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const TickType_t xTimerPeriodInTicks, const BaseType_t xAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, Timer_t * pxNewTimer ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ BaseType_t xTimerCreateTimerTask( void ) { BaseType_t xReturn = pdFAIL; /* This function is called when the scheduler is started if * configUSE_TIMERS is set to 1. Check that the infrastructure used by the * timer service task has been created/initialised. If timers have already * been created then the initialisation will already have been performed. */ prvCheckForValidListAndQueue(); if( xTimerQueue != NULL ) { #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) { StaticTask_t * pxTimerTaskTCBBuffer = NULL; StackType_t * pxTimerTaskStackBuffer = NULL; uint32_t ulTimerTaskStackSize; vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize ); xTimerTaskHandle = xTaskCreateStatic( prvTimerTask, configTIMER_SERVICE_TASK_NAME, ulTimerTaskStackSize, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, pxTimerTaskStackBuffer, pxTimerTaskTCBBuffer ); if( xTimerTaskHandle != NULL ) { xReturn = pdPASS; } } #else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ { xReturn = xTaskCreate( prvTimerTask, configTIMER_SERVICE_TASK_NAME, configTIMER_TASK_STACK_DEPTH, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle ); } #endif /* configSUPPORT_STATIC_ALLOCATION */ } else { mtCOVERAGE_TEST_MARKER(); } configASSERT( xReturn ); return xReturn; } /*-----------------------------------------------------------*/ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const TickType_t xTimerPeriodInTicks, const BaseType_t xAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) { Timer_t * pxNewTimer; pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of Timer_t is always a pointer to the timer's mame. */ if( pxNewTimer != NULL ) { /* Status is thus far zero as the timer is not created statically * and has not been started. The auto-reload bit may get set in * prvInitialiseNewTimer. */ pxNewTimer->ucStatus = 0x00; prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, xAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); } return pxNewTimer; } #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ /*-----------------------------------------------------------*/ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const TickType_t xTimerPeriodInTicks, const BaseType_t xAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t * pxTimerBuffer ) { Timer_t * pxNewTimer; #if ( configASSERT_DEFINED == 1 ) { /* Sanity check that the size of the structure used to declare a * variable of type StaticTimer_t equals the size of the real timer * structure. */ volatile size_t xSize = sizeof( StaticTimer_t ); configASSERT( xSize == sizeof( Timer_t ) ); ( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */ } #endif /* configASSERT_DEFINED */ /* A pointer to a StaticTimer_t structure MUST be provided, use it. */ configASSERT( pxTimerBuffer ); pxNewTimer = ( Timer_t * ) pxTimerBuffer; /*lint !e740 !e9087 StaticTimer_t is a pointer to a Timer_t, so guaranteed to be aligned and sized correctly (checked by an assert()), so this is safe. */ if( pxNewTimer != NULL ) { /* Timers can be created statically or dynamically so note this * timer was created statically in case it is later deleted. The * auto-reload bit may get set in prvInitialiseNewTimer(). */ pxNewTimer->ucStatus = tmrSTATUS_IS_STATICALLY_ALLOCATED; prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, xAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); } return pxNewTimer; } #endif /* configSUPPORT_STATIC_ALLOCATION */ /*-----------------------------------------------------------*/ static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const TickType_t xTimerPeriodInTicks, const BaseType_t xAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, Timer_t * pxNewTimer ) { /* 0 is not a valid value for xTimerPeriodInTicks. */ configASSERT( ( xTimerPeriodInTicks > 0 ) ); /* Ensure the infrastructure used by the timer service task has been * created/initialised. */ prvCheckForValidListAndQueue(); /* Initialise the timer structure members using the function * parameters. */ pxNewTimer->pcTimerName = pcTimerName; pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; pxNewTimer->pvTimerID = pvTimerID; pxNewTimer->pxCallbackFunction = pxCallbackFunction; vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); if( xAutoReload != pdFALSE ) { pxNewTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD; } traceTIMER_CREATE( pxNewTimer ); } /*-----------------------------------------------------------*/ BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) { BaseType_t xReturn = pdFAIL; DaemonTaskMessage_t xMessage; configASSERT( xTimer ); /* Send a message to the timer service task to perform a particular action * on a particular timer definition. */ if( xTimerQueue != NULL ) { /* Send a command to the timer service task to start the xTimer timer. */ xMessage.xMessageID = xCommandID; xMessage.u.xTimerParameters.xMessageValue = xOptionalValue; xMessage.u.xTimerParameters.pxTimer = xTimer; if( xCommandID < tmrFIRST_FROM_ISR_COMMAND ) { if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING ) { xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); } else { xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY ); } } else { xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); } traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn ); } else { mtCOVERAGE_TEST_MARKER(); } return xReturn; } /*-----------------------------------------------------------*/ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) { /* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been * started, then xTimerTaskHandle will be NULL. */ configASSERT( ( xTimerTaskHandle != NULL ) ); return xTimerTaskHandle; } /*-----------------------------------------------------------*/ TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) { Timer_t * pxTimer = xTimer; configASSERT( xTimer ); return pxTimer->xTimerPeriodInTicks; } /*-----------------------------------------------------------*/ void vTimerSetReloadMode( TimerHandle_t xTimer, const BaseType_t xAutoReload ) { Timer_t * pxTimer = xTimer; configASSERT( xTimer ); taskENTER_CRITICAL(); { if( xAutoReload != pdFALSE ) { pxTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD; } else { pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_AUTORELOAD ); } } taskEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ BaseType_t xTimerGetReloadMode( TimerHandle_t xTimer ) { Timer_t * pxTimer = xTimer; BaseType_t xReturn; configASSERT( xTimer ); taskENTER_CRITICAL(); { if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) == 0 ) { /* Not an auto-reload timer. */ xReturn = pdFALSE; } else { /* Is an auto-reload timer. */ xReturn = pdTRUE; } } taskEXIT_CRITICAL(); return xReturn; } UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer ) { return ( UBaseType_t ) xTimerGetReloadMode( xTimer ); } /*-----------------------------------------------------------*/ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) { Timer_t * pxTimer = xTimer; TickType_t xReturn; configASSERT( xTimer ); xReturn = listGET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ) ); return xReturn; } /*-----------------------------------------------------------*/ const char * pcTimerGetName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ { Timer_t * pxTimer = xTimer; configASSERT( xTimer ); return pxTimer->pcTimerName; } /*-----------------------------------------------------------*/ static void prvReloadTimer( Timer_t * const pxTimer, TickType_t xExpiredTime, const TickType_t xTimeNow ) { /* Insert the timer into the appropriate list for the next expiry time. * If the next expiry time has already passed, advance the expiry time, * call the callback function, and try again. */ while( prvInsertTimerInActiveList( pxTimer, ( xExpiredTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xExpiredTime ) != pdFALSE ) { /* Advance the expiry time. */ xExpiredTime += pxTimer->xTimerPeriodInTicks; /* Call the timer callback. */ traceTIMER_EXPIRED( pxTimer ); pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); } } /*-----------------------------------------------------------*/ static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) { Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ /* Remove the timer from the list of active timers. A check has already * been performed to ensure the list is not empty. */ ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); /* If the timer is an auto-reload timer then calculate the next * expiry time and re-insert the timer in the list of active timers. */ if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) { prvReloadTimer( pxTimer, xNextExpireTime, xTimeNow ); } else { pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); } /* Call the timer callback. */ traceTIMER_EXPIRED( pxTimer ); pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); } /*-----------------------------------------------------------*/ static portTASK_FUNCTION( prvTimerTask, pvParameters ) { TickType_t xNextExpireTime; BaseType_t xListWasEmpty; /* Just to avoid compiler warnings. */ ( void ) pvParameters; #if ( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 ) { extern void vApplicationDaemonTaskStartupHook( void ); /* Allow the application writer to execute some code in the context of * this task at the point the task starts executing. This is useful if the * application includes initialisation code that would benefit from * executing after the scheduler has been started. */ vApplicationDaemonTaskStartupHook(); } #endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */ for( ; ; ) { /* Query the timers list to see if it contains any timers, and if so, * obtain the time at which the next timer will expire. */ xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty ); /* If a timer has expired, process it. Otherwise, block this task * until either a timer does expire, or a command is received. */ prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty ); /* Empty the command queue. */ prvProcessReceivedCommands(); } } /*-----------------------------------------------------------*/ static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty ) { TickType_t xTimeNow; BaseType_t xTimerListsWereSwitched; vTaskSuspendAll(); { /* Obtain the time now to make an assessment as to whether the timer * has expired or not. If obtaining the time causes the lists to switch * then don't process this timer as any timers that remained in the list * when the lists were switched will have been processed within the * prvSampleTimeNow() function. */ xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); if( xTimerListsWereSwitched == pdFALSE ) { /* The tick count has not overflowed, has the timer expired? */ if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) ) { ( void ) xTaskResumeAll(); prvProcessExpiredTimer( xNextExpireTime, xTimeNow ); } else { /* The tick count has not overflowed, and the next expire * time has not been reached yet. This task should therefore * block to wait for the next expire time or a command to be * received - whichever comes first. The following line cannot * be reached unless xNextExpireTime > xTimeNow, except in the * case when the current timer list is empty. */ if( xListWasEmpty != pdFALSE ) { /* The current timer list is empty - is the overflow list * also empty? */ xListWasEmpty = listLIST_IS_EMPTY( pxOverflowTimerList ); } vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ), xListWasEmpty ); if( xTaskResumeAll() == pdFALSE ) { /* Yield to wait for either a command to arrive, or the * block time to expire. If a command arrived between the * critical section being exited and this yield then the yield * will not cause the task to block. */ portYIELD_WITHIN_API(); } else { mtCOVERAGE_TEST_MARKER(); } } } else { ( void ) xTaskResumeAll(); } } } /*-----------------------------------------------------------*/ static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) { TickType_t xNextExpireTime; /* Timers are listed in expiry time order, with the head of the list * referencing the task that will expire first. Obtain the time at which * the timer with the nearest expiry time will expire. If there are no * active timers then just set the next expire time to 0. That will cause * this task to unblock when the tick count overflows, at which point the * timer lists will be switched and the next expiry time can be * re-assessed. */ *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList ); if( *pxListWasEmpty == pdFALSE ) { xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); } else { /* Ensure the task unblocks when the tick count rolls over. */ xNextExpireTime = ( TickType_t ) 0U; } return xNextExpireTime; } /*-----------------------------------------------------------*/ static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) { TickType_t xTimeNow; PRIVILEGED_DATA static TickType_t xLastTime = ( TickType_t ) 0U; /*lint !e956 Variable is only accessible to one task. */ xTimeNow = xTaskGetTickCount(); if( xTimeNow < xLastTime ) { prvSwitchTimerLists(); *pxTimerListsWereSwitched = pdTRUE; } else { *pxTimerListsWereSwitched = pdFALSE; } xLastTime = xTimeNow; return xTimeNow; } /*-----------------------------------------------------------*/ static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) { BaseType_t xProcessTimerNow = pdFALSE; listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime ); listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); if( xNextExpiryTime <= xTimeNow ) { /* Has the expiry time elapsed between the command to start/reset a * timer was issued, and the time the command was processed? */ if( ( ( TickType_t ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks ) /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ { /* The time between a command being issued and the command being * processed actually exceeds the timers period. */ xProcessTimerNow = pdTRUE; } else { vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) ); } } else { if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) ) { /* If, since the command was issued, the tick count has overflowed * but the expiry time has not, then the timer must have already passed * its expiry time and should be processed immediately. */ xProcessTimerNow = pdTRUE; } else { vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); } } return xProcessTimerNow; } /*-----------------------------------------------------------*/ static void prvProcessReceivedCommands( void ) { DaemonTaskMessage_t xMessage; Timer_t * pxTimer; BaseType_t xTimerListsWereSwitched; TickType_t xTimeNow; while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */ { #if ( INCLUDE_xTimerPendFunctionCall == 1 ) { /* Negative commands are pended function calls rather than timer * commands. */ if( xMessage.xMessageID < ( BaseType_t ) 0 ) { const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters ); /* The timer uses the xCallbackParameters member to request a * callback be executed. Check the callback is not NULL. */ configASSERT( pxCallback ); /* Call the function. */ pxCallback->pxCallbackFunction( pxCallback->pvParameter1, pxCallback->ulParameter2 ); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* INCLUDE_xTimerPendFunctionCall */ /* Commands that are positive are timer commands rather than pended * function calls. */ if( xMessage.xMessageID >= ( BaseType_t ) 0 ) { /* The messages uses the xTimerParameters member to work on a * software timer. */ pxTimer = xMessage.u.xTimerParameters.pxTimer; if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) /*lint !e961. The cast is only redundant when NULL is passed into the macro. */ { /* The timer is in a list, remove it. */ ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); } else { mtCOVERAGE_TEST_MARKER(); } traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue ); /* In this case the xTimerListsWereSwitched parameter is not used, but * it must be present in the function call. prvSampleTimeNow() must be * called after the message is received from xTimerQueue so there is no * possibility of a higher priority task adding a message to the message * queue with a time that is ahead of the timer daemon task (because it * pre-empted the timer daemon task after the xTimeNow value was set). */ xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); switch( xMessage.xMessageID ) { case tmrCOMMAND_START: case tmrCOMMAND_START_FROM_ISR: case tmrCOMMAND_RESET: case tmrCOMMAND_RESET_FROM_ISR: /* Start or restart a timer. */ pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE; if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE ) { /* The timer expired before it was added to the active * timer list. Process it now. */ if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) { prvReloadTimer( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow ); } else { pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); } /* Call the timer callback. */ traceTIMER_EXPIRED( pxTimer ); pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); } else { mtCOVERAGE_TEST_MARKER(); } break; case tmrCOMMAND_STOP: case tmrCOMMAND_STOP_FROM_ISR: /* The timer has already been removed from the active list. */ pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); break; case tmrCOMMAND_CHANGE_PERIOD: case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR: pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE; pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue; configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); /* The new period does not really have a reference, and can * be longer or shorter than the old one. The command time is * therefore set to the current time, and as the period cannot * be zero the next expiry time can only be in the future, * meaning (unlike for the xTimerStart() case above) there is * no fail case that needs to be handled here. */ ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); break; case tmrCOMMAND_DELETE: #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) { /* The timer has already been removed from the active list, * just free up the memory if the memory was dynamically * allocated. */ if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) 0 ) { vPortFree( pxTimer ); } else { pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); } } #else /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ { /* If dynamic allocation is not enabled, the memory * could not have been dynamically allocated. So there is * no need to free the memory - just mark the timer as * "not active". */ pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); } #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ break; default: /* Don't expect to get here. */ break; } } } } /*-----------------------------------------------------------*/ static void prvSwitchTimerLists( void ) { TickType_t xNextExpireTime; List_t * pxTemp; /* The tick count has overflowed. The timer lists must be switched. * If there are any timers still referenced from the current timer list * then they must have expired and should be processed before the lists * are switched. */ while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE ) { xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); /* Process the expired timer. For auto-reload timers, be careful to * process only expirations that occur on the current list. Further * expirations must wait until after the lists are switched. */ prvProcessExpiredTimer( xNextExpireTime, tmrMAX_TIME_BEFORE_OVERFLOW ); } pxTemp = pxCurrentTimerList; pxCurrentTimerList = pxOverflowTimerList; pxOverflowTimerList = pxTemp; } /*-----------------------------------------------------------*/ static void prvCheckForValidListAndQueue( void ) { /* Check that the list from which active timers are referenced, and the * queue used to communicate with the timer service, have been * initialised. */ taskENTER_CRITICAL(); { if( xTimerQueue == NULL ) { vListInitialise( &xActiveTimerList1 ); vListInitialise( &xActiveTimerList2 ); pxCurrentTimerList = &xActiveTimerList1; pxOverflowTimerList = &xActiveTimerList2; #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) { /* The timer queue is allocated statically in case * configSUPPORT_DYNAMIC_ALLOCATION is 0. */ PRIVILEGED_DATA static StaticQueue_t xStaticTimerQueue; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ PRIVILEGED_DATA static uint8_t ucStaticTimerQueueStorage[ ( size_t ) configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, ( UBaseType_t ) sizeof( DaemonTaskMessage_t ), &( ucStaticTimerQueueStorage[ 0 ] ), &xStaticTimerQueue ); } #else { xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) ); } #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ #if ( configQUEUE_REGISTRY_SIZE > 0 ) { if( xTimerQueue != NULL ) { vQueueAddToRegistry( xTimerQueue, "TmrQ" ); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* configQUEUE_REGISTRY_SIZE */ } else { mtCOVERAGE_TEST_MARKER(); } } taskEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) { BaseType_t xReturn; Timer_t * pxTimer = xTimer; configASSERT( xTimer ); /* Is the timer in the list of active timers? */ taskENTER_CRITICAL(); { if( ( pxTimer->ucStatus & tmrSTATUS_IS_ACTIVE ) == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } } taskEXIT_CRITICAL(); return xReturn; } /*lint !e818 Can't be pointer to const due to the typedef. */ /*-----------------------------------------------------------*/ void * pvTimerGetTimerID( const TimerHandle_t xTimer ) { Timer_t * const pxTimer = xTimer; void * pvReturn; configASSERT( xTimer ); taskENTER_CRITICAL(); { pvReturn = pxTimer->pvTimerID; } taskEXIT_CRITICAL(); return pvReturn; } /*-----------------------------------------------------------*/ void vTimerSetTimerID( TimerHandle_t xTimer, void * pvNewID ) { Timer_t * const pxTimer = xTimer; configASSERT( xTimer ); taskENTER_CRITICAL(); { pxTimer->pvTimerID = pvNewID; } taskEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ #if ( INCLUDE_xTimerPendFunctionCall == 1 ) BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void * pvParameter1, uint32_t ulParameter2, BaseType_t * pxHigherPriorityTaskWoken ) { DaemonTaskMessage_t xMessage; BaseType_t xReturn; /* Complete the message with the function parameters and post it to the * daemon task. */ xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR; xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; xReturn = xQueueSendFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); tracePEND_FUNC_CALL_FROM_ISR( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); return xReturn; } #endif /* INCLUDE_xTimerPendFunctionCall */ /*-----------------------------------------------------------*/ #if ( INCLUDE_xTimerPendFunctionCall == 1 ) BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void * pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) { DaemonTaskMessage_t xMessage; BaseType_t xReturn; /* This function can only be called after a timer has been created or * after the scheduler has been started because, until then, the timer * queue does not exist. */ configASSERT( xTimerQueue ); /* Complete the message with the function parameters and post it to the * daemon task. */ xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK; xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); tracePEND_FUNC_CALL( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); return xReturn; } #endif /* INCLUDE_xTimerPendFunctionCall */ /*-----------------------------------------------------------*/ #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) { return ( ( Timer_t * ) xTimer )->uxTimerNumber; } #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ #if ( configUSE_TRACE_FACILITY == 1 ) void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber ) { ( ( Timer_t * ) xTimer )->uxTimerNumber = uxTimerNumber; } #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ /* This entire source file will be skipped if the application is not configured * to include software timer functionality. If you want to include software timer * functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ #endif /* configUSE_TIMERS == 1 */ ================================================ FILE: FreeRTOS-comparison/version_FeeRTOS-202210-LTS.txt ================================================ This directory is the FreeRTOS Kernel part of the FreeRTOS 202210 LTS. To reduce the size, the portable sub-directory has been pruned and several FreeRTOS ports have been removed. ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2021 Quantum Leaps, . Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ ## Brought to you by: [![Quantum Leaps](https://www.state-machine.com/attachments/logo_ql_400.png)](https://www.state-machine.com)
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/QuantumLeaps/Super-Simple-Tasker)](https://github.com/QuantumLeaps/Super-Simple-Tasker/releases/latest) [![GitHub](https://img.shields.io/github/license/QuantumLeaps/Super-Simple-Tasker)](https://github.com/QuantumLeaps/Super-Simple-Tasker/blob/master/LICENSE) # Super-Simple Tasker (SST) Super-Simple Tasker (SST) is an event-driven, preemptive, priority-based real-time operating system (RTOS) kernel that is fully compatible with the requirements of [Rate Monotonic Analysis/Scheduling (RMA/RMS)](https://youtu.be/kLxxXNCrY60).

The tasks in SST are non-blocking and run-to-completion, which are also known as **basic tasks** in the [OSEK/VDX Operating System Specification](https://www.irisa.fr/alf/downloads/puaut/TPNXT/images/os223.pdf). SST corresponds to the BCC2 conformance class in OSEK/VDX. SST provides the following features: - basic tasks (non-blocking, run-to-completion) - preemptive, priority-based scheduling - multiple tasks per priority level - multiple "activations" per task (event queues) - selective scheduler locking according to "Stack Resource Policy" (SRP)
(a non-blocking mutual exclusion mechanism for protecting shared resources) > **NOTE**
The execution profile of SST tasks perfectly matches the non-blocking and run-to-completion semantics of event-driven state machines (a.k.a. ["Active Objects" or "Actors](https://www.state-machine.com/active-object)). This repository contains the SST following implementations: - [preemptive SST in C](sst_c) - [preemptive SST in C++](sst_cpp) Additionally, this repository contains the even simpler, *non-preemptive* implementation of basic tasks called [SST0](#non-preemptive-sst0): - [non-preemptive SST0 in C](sst0_c) - [non-preemptive SST0 in C++](sst0_cpp) > **NOTE**
The preemptive SST and non-preemptive SST0 implement actually *the same* [SST API](https://github.com/QuantumLeaps/Super-Simple-Tasker/tree/main/include) (either in C or C++). ## Related Approaches The SST RTOS kernel is related to, although *not* based on, the following approaches: - [Operating System - OSEK VDX](https://www.osek-vdx.org/mirror/os21r1.pdf) - [A Stack-Based Resource Allocation Policy for Realtime Processes](https://ieeexplore.ieee.org/document/128747) - [Real-Time For the Masses](https://www.diva-portal.org/smash/get/diva2:1005680/FULLTEXT01.pdf) - [crect: A C++, compile-time, reactive RTOS](https://github.com/korken89/crect) - [Rust's Real Time For the Masses (RTFM)](https://lonesometraveler.github.io/2020/05/22/RTFM.html) - [Real-Time Interrupt-driven Concurrency (RTIC)](https://rtic.rs/1/book/en) # Hardware RTOS for ARM Cortex-M [SST for ARM Cortex-M](sst_c/ports/arm-cm) provides a unique **hardware implementation** of the SST API for ARM Cortex-M (M0, M0+, M3, M4, M7, M23, M33). The SST "hardware RTOS" for ARM Cortex-M is fully compatible with the requirements of [Rate Monotonic Analysis/Scheduling (RMA/RMS)](https://youtu.be/kLxxXNCrY60).

> **NOTE**
The SST hardware implementation is likely the most performant and efficient **hard-real time RTOS** kernel for ARM Cortex-M. # Hardware RTOS for Microchip dsPIC The contributed [SST port for dsPIC](sst_c/ports/dspic) provides a unique **hardware implementation** of the SST API for [Microchip dsPIC](https://www.microchip.com/en-us/products/microcontrollers-and-microprocessors/dspic-dscs). The SST "hardware RTOS" for dsPIC is fully compatible with the requirements of [Rate Monotonic Analysis/Scheduling (RMA/RMS)](https://youtu.be/kLxxXNCrY60).

# SST Videos SST has been presented at the Embedded Online Conference 2023 and the videos are available on YouTube:

# SST History SST has been originally published as a cover-story article ["Build a Super-Simple Tasker"](legacy/Super-Simple-Tasker.pdf) in the Embedded Systems Design magazine in [July 2006](https://www.embedded.com/embedded-systems-design-july-2006). That original version of SST (now called "Legacy SST") is [still available](legacy) and is provided for historical reference. Over the years, more complete SST-like kernels have been developed for a number of embedded processors, such as: ARM7TDMI, ARM Cortex-M (M0-M7), ARM Cortex-R, MSP430, PIC24/dsPIC, PIC32, etc. All these kernels are now included in the [QP/C and QP/C++ Real-Time Embedded Frameworks](https://www.state-machine.com/products/qp): - [QK preemptive, priority-based, non-blocking kernel](https://www.state-machine.com/qpc/srs_qk.html) works like SST and is available as one of the built-in kernels in the [QP Real-Time Embedded Frameworks (RTEFs)](https://www.state-machine.com/products/qp). - [QXK preemptive, dual-mode kernel](https://www.state-machine.com/qpc/srs_qxk.html) combines the basic-tasks of SST with traditional blocking tasks (a.k.a. **extended tasks** in OSEK/VDX) and is available as one of the built-in kernels in the [QP Real-Time Embedded Frameworks (RTEFs)](https://www.state-machine.com/products/qp) - [QV priority-based, cooperative kernel](https://www.state-machine.com/qpc/srs_qv.html) works like [SST0](#non-preemptive-sst0) and is available as one of the built-in kernels in the [QP Real-Time Embedded Frameworks (RTEFs)](https://www.state-machine.com/products) # Non-Preemptive SST0 This repository contains also the non-preemptive implementation of the SST API, called **SST0**. SST0 is also a **priority-based RTOS kernel**, but the scheduling is non-preemptive. SST0 scheduler always executes the highest-priority basic task ready to run, but the scheduling is performed only after voluntary completion of each task (run-to-completion execution).

SST0 provides the following features: - basic tasks (non-blocking, run-to-completion) - priority-based, non-preemptive (cooperative) scheduling - only one task per priority level - multiple "activations" per task (event queues) # Getting Started / Examples The best way to get started with SST is to build and run the provided **examples**. This repository contains several versions of the **"blinky-button" example**, which contains several SST tasks running concurrently and communicating with each other. The "blinky-button" example demonstrates **real-time** capabilities of SST and uses a logic analyzer. (REMARK: Logic analyzer is not necessary to build and run the examples.)

The "blinky-button" example is provided for: ```c Super-Simple-Tasker/ | +---sst_c/ // preemptive SST/C | +----examples/ // examples for SST/C | | +----blinky_button/ // "blinky-button" example | | | +----armclang/ // project for ARM/KEIL | | | +----gnu/ // makefile for GNU-ARM | | | +----iar/ // project for IAR EWARM | +---sst_cpp/ // preemptive SST/C++ | +----examples/ // examples for SST/C++ | | +----blinky_button/ // "blinky-button" example | | | +----armclang/ // project for ARM/KEIL | | | +----gnu/ // makefile for GNU-ARM | | | +----iar/ // project for IAR EWARM | +---sst0_c/ // non-preemptive SST0/C | +----examples/ // examples for SST0/C | | +----blinky_button/ // "blinky-button" example | | | +----armclang/ // project for ARM/KEIL | | | +----gnu/ // makefile for GNU-ARM | | | +----iar/ // project for IAR EWARM | +---sst0_cpp/ // non-preemptive SST0/C++ | +----examples/ // examples for SST0/C++ | | +----blinky_button/ // "blinky-button" example | | | +----armclang/ // project for ARM/KEIL | | | +----gnu/ // makefile for GNU-ARM | | | +----iar/ // project for IAR EWARM | ``` For **every** of these cases the projects to build the examples are provided for the following embedded boards:

- **STM32 NUCLEO-C031C6** (ARM Cortex-M0+) - **STM32 NUCLEO-L053R8** (ARM Cortex-M0+) - **STM32 NUCLEO-H743ZI** (ARM Cortex-M7 with double-precision FPU) - **TivaC LaunchPad (EK-TM4C123GXL)** (ARM Cortex-M4 with single-precision FPU) # Licensing The SST source code and examples are released under the terms of the permissive [MIT open source license](LICENSE). Please note that the attribution clause in the MIT license requires you to preserve the original copyright notice in all changes and derivate works. # Invitation to Collaborate **This project welcomes collaboration!** Please help to improve SST, port it to other processors, integrate it with other embedded software, add interesting examples, etc. To avoid fragmentation, this repository is intended to remain the home of SST. To contribute, please clone, fork, and submit **pull requests** to incorporate your changes. # How to Help this Project? If you like this project, please **spread the word** about SST on various forums, social media, and other venues frequented by embedded folks!

Also, please give [this repository](https://github.com/QuantumLeaps/Super-Simple-Tasker) a star (in the upper-right corner of your browser window)

================================================ FILE: img/blinky_button.pvs ================================================ [General] decode_signals=0 generated_signals=0 views=1 meta_objs=1 [D0] name=Button enabled=true color=4279638298 conversion_type=0 conv_options=0 [D1] name=SysTick enabled=true color=4287582722 conversion_type=0 conv_options=0 [D2] name=Blinky3 enabled=true color=4291559424 conversion_type=0 conv_options=0 [D3] name=Button2b enabled=true color=4294277376 conversion_type=0 conv_options=0 [D4] name=Button2a enabled=true color=4293776384 conversion_type=0 conv_options=0 [D5] name=Blinky1 enabled=true color=4285780502 conversion_type=0 conv_options=0 [D6] name=idle enabled=true color=4281623972 conversion_type=0 conv_options=0 [D7] name=D7 enabled=false color=4285878395 conversion_type=0 conv_options=0 [view0] scale=2.774822375165226e-7 v_offset=-10 splitter_state=@ByteArray(\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\0^\0\0\x6\xd9\x1\0\0\0\x1\x1\0\0\0\x1\0) segment_display_mode=3 offset=22 serialization::archive 14 0 0 0 0 565494 56196546 79329487 74204364 71079248 21742675 -8 0 0 6 zero_offset=22 serialization::archive 14 0 0 0 0 0 0 0 0 0 0 0 0 0 6 D0\trace_height=80 D1\trace_height=80 D2\trace_height=80 D3\trace_height=80 D4\trace_height=80 D5\trace_height=80 D6\trace_height=80 D7\trace_height=80 [meta_obj0] type=selection assoc_view=0 start_time=22 serialization::archive 14 0 0 0 0 568183 33333333 33006798 23807399 77088523 24049645 -8 0 0 6 end_time=22 serialization::archive 14 0 0 0 0 568758 33333333 33553138 98849203 72423947 75779883 -8 0 0 6 ================================================ FILE: include/README.txt ================================================ This directory contains the following SST API definitions: - sst.h -- SST API in C - sst.hpp -- SST API in C++ NOTE: The SST API is the same for various SST implementatinons, such as the preemptive SST and the non-preemptive SST0. ================================================ FILE: include/dbc_assert.h ================================================ /*============================================================================ * Design By Contract (DBC) for embedded C and C++ * GitHub: https://github.com/QuantumLeaps/DBC-for-embedded-C * * Q u a n t u m L e a P s * ------------------------ * Modern Embedded Software * * Copyright (C) 2005 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #ifndef DBC_ASSERT_H_ #define DBC_ASSERT_H_ /*! @file * @brief Memory-efficient Design by Contract (DBC) for embedded C and C++. * * @note * The runtime checking of the DBC assertions can be disabled by defining * the macro #DBC_DISABLE. However, it is generally **not** advisable to * disable assertions, *especially* in the production code. Instead, the * assertion fault handler DBC_fault_handler() should be very carefully * designed and tested under all fault conditions. */ /* Active DbC macros -------------------------------------------------------*/ #ifndef DBC_DISABLE /*! Define the user-specified module name for assertions in this file. * * @details * Macro to be placed at the top of each C/C++ module to define the * single instance of the module name string to be used in reporting * assertions in this module. This macro takes the user-supplied parameter * `name_`. * * @param[in] name_ string constant representing the module name * * @note * This macro should **not** be terminated by a semicolon. */ #define DBC_MODULE_NAME(name_) \ static char const DBC_module_name_[] = name_; /*! General purpose assertion with user-specified ID number. * * @details * Makes sure the `expr_` parameter is TRUE. Calls the DBC_fault_handler() * callback if the `expr_` evaluates to FALSE. This assertion takes the * user-supplied parameter `label_` to identify the location of this * assertion within the module. This avoids the volatility of using line * numbers, which change whenever a line of code is added or removed * upstream from the assertion. * * @param[in] label_ numeric label of the assertion (unique within the module) * @param[in] expr_ Boolean expression to check * * @note * The `expr_` expression is **not** evaluated if assertions are * disabled with the ::DBC_DISABLE switch. */ #define DBC_ASSERT(label_, expr_) ((expr_) \ ? ((void)0) : DBC_fault_handler(&DBC_module_name_[0], (label_))) /*! General purpose assertion with user-specified ID number that * evaluates the `expr_` expression even when assertions are disabled. * * @details * Like the DBC_ASSERT() macro, except it **always** evaluates the * `expr_` expression even when DBC assertions are disabled with the * #DBC_DISABLE macro. * * @param[in] label_ numeric label of the assertion (unique within the module) * @param[in] expr_ Boolean expression to check */ #define DBC_ALLEGE(label_, expr_) DBC_ASSERT(label_, expr_) /*! Assertion for a wrong path through the code * * @details * Calls the DBC_fault_handler() callback if ever executed. This assertion * takes the user-supplied parameter `id_` to identify the location of * this assertion within the file. This avoids the volatility of using * line numbers, which change whenever a line of code is added or removed * upstream from the assertion. * * @param[in] label_ numeric label of the assertion (unique within the module) */ #define DBC_ERROR(label_) DBC_fault_handler(&DBC_module_name_[0], (label_)) /*! Assertion for checking preconditions. * * @details * Equivalent to DBC_ASSERT(), except the name provides a better * documentation of the intention of this assertion. * * @param[in] label_ numeric label of the assertion (unique within the module) * @param[in] expr_ Boolean expression to check * * @note * The `expr_` expression is **not** evaluated if assertions are * disabled with the ::DBC_DISABLE switch. */ #define DBC_REQUIRE(label_, expr_) DBC_ASSERT((label_), (expr_)) /*! Assertion for checking postconditions. * * @details * Equivalent to DBC_ASSERT(), except the name provides a better * documentation of the intention of this assertion. * * @param[in] label_ numeric label of the assertion (unique within the module) * @param[in] expr_ Boolean expression to check * * @note * The `expr_` expression is **not** evaluated if assertions are * disabled with the ::DBC_DISABLE switch. */ #define DBC_ENSURE(label_, expr_) DBC_ASSERT((label_), (expr_)) /*! Assertion for checking invariants. * * @details * Equivalent to DBC_ASSERT(), except the name provides a better * documentation of the intention of this assertion. * * @param[in] label_ numeric label of the assertion (unique within the module) * @param[in] expr_ Boolean expression to check * * @note * The `expr_` expression is **not** evaluated if assertions are * disabled with the ::DBC_DISABLE switch. */ #define DBC_INVARIANT(label_, expr_) DBC_ASSERT((label_), (expr_)) #ifndef DBC_NORETURN #define DBC_NORETURN #endif #ifdef __cplusplus extern "C" { #endif /*! DBC assertion fault handler. * * @details * This is an application-specific callback function needs to be defined in * the application to perform the clean system shutdown and perhaps a reset. * The DBC_fault_handler() function is the last line of defense after the * system failure and its implementation should be very **carefully** * designed and **tested** under various fault conditions, including but * not limited to: stack overflow, stack corruption, or calling * DBC_fault_handler() from ISRs. * @param[in] module name of the file/module in which the assertion failed * (constant, zero-terminated C string) * @param[in] label unique label of the assertion within the module. * This could be a line number or a user-defined label. * * @returns * This callback function should **not return** (see #NORETURN), * as continuation after an assertion failure does not make sense. * * @note * It is typically a **bad idea** to implement DBC_fault_handler() as an * endless loop that ties up the CPU. During debugging, DBC_fault_handler() * is an ideal place to put a breakpoint. */ DBC_NORETURN void DBC_fault_handler(char const * module, int label); #ifdef __cplusplus } #endif /* Inactive DbC macros -----------------------------------------------------*/ #else #define DBC_MODULE_NAME(dummy_) #define DBC_ASSERT(label_, expr_) ((void)0) #define DBC_ERROR(label_) ((void)0) #define DBC_REQUIRE(label_, expr_) ((void)0) #define DBC_ENSURE(label_, expr_) ((void)0) #define DBC_INVARIANT(label_, expr_) ((void)0) #define DBC_ALLEGE(label_, expr_) ((void)(expr_)) #endif /* Inactive DBC macros */ #endif /* DBC_ASSERT_ */ ================================================ FILE: include/sst.h ================================================ /*=========================================================================== * Super-Simple Tasker (SST/C) API * * Copyright (C) 2005-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ===========================================================================*/ #ifndef SST_H_ #define SST_H_ #include /* standard C99 integers */ #include /* standard C99 Boolean */ #include "sst_port.h" /* SST port for specific CPU */ /* SST Event facilities ----------------------------------------------------*/ /*! signal of SST event */ typedef uint16_t SST_Signal; /*! SST event class */ typedef struct { SST_Signal sig; } SST_Evt; /*! macro for downcasting SST events to specific Evt "subclasses" */ #define SST_EVT_DOWNCAST(EVT_, e_) ((EVT_ const *)(e_)) /* SST Task facilities -----------------------------------------------------*/ typedef struct SST_Task SST_Task; /* forward declaration */ /*! SST Task priority */ typedef uint8_t SST_TaskPrio; /*! SST internal event-queue counter */ typedef uint8_t SST_QCtr; /*! generic handler signature */ typedef void (*SST_Handler)(SST_Task * const me, SST_Evt const * const e); /*! SST task (a.k.a. "Active Object") */ struct SST_Task { SST_Handler init; SST_Handler dispatch; SST_Evt const **qBuf; /*!< ring buffer for the queue */ SST_QCtr end; /*!< last index into the ring buffer */ SST_QCtr head; /*!< index for inserting events */ SST_QCtr tail; /*!< index for removing events */ SST_QCtr nUsed; /*!< # used entries currently in the queue */ #ifdef SST_PORT_TASK_ATTR SST_PORT_TASK_ATTR #endif }; void SST_Task_ctor( SST_Task * const me, SST_Handler init, SST_Handler dispatch); void SST_Task_start( SST_Task * const me, SST_TaskPrio prio, SST_Evt const **qBuf, SST_QCtr qLen, SST_Evt const * const ie); void SST_Task_post(SST_Task * const me, SST_Evt const * const e); int SST_Task_run(void); /* run SST tasks static */ #ifdef SST_PORT_TASK_OPER /* additional Task operations needed by the specific SST port */ SST_PORT_TASK_OPER #endif /* lock the SST task scheduler up to the provided priority ceiling (SRP) */ SST_LockKey SST_Task_lock(SST_TaskPrio ceiling); /* unlock the SST task scheduler with the provided lock key */ void SST_Task_unlock(SST_LockKey lock_key); /* SST Time Event facilities -----------------------------------------------*/ /*! SST internal time-event tick counter */ typedef uint16_t SST_TCtr; /*! SST time event class */ typedef struct SST_TimeEvt SST_TimeEvt; struct SST_TimeEvt { SST_Evt super; SST_TimeEvt *next; /*! link to next time event in a link-list */ SST_Task *task; /*! the owner task to post time event to */ SST_TCtr ctr; /*! time event down-counter */ SST_TCtr interval; /*! interval for periodic time event */ }; void SST_TimeEvt_ctor( SST_TimeEvt * const me, SST_Signal sig, SST_Task *task); void SST_TimeEvt_arm( SST_TimeEvt * const me, SST_TCtr ctr, SST_TCtr interval); bool SST_TimeEvt_disarm( SST_TimeEvt * const me); void SST_TimeEvt_tick(void); /* static handle all instantiated time events */ /* SST Kernel facilities ---------------------------------------------------*/ void SST_init(void); void SST_start(void); void SST_onStart(void); /* general convenience utilities -------------------------------------------*/ #ifndef ARRAY_NELEM /*! convenience macro to provide the number of elements in the array a_ */ #define ARRAY_NELEM(a_) (sizeof(a_) / sizeof((a_)[0])) #endif /* ARRAY_NELEM */ #endif /* SST_H_ */ ================================================ FILE: include/sst.hpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #ifndef SST_HPP_ #define SST_HPP_ #include // standard integer types #include "sst_port.hpp" // SST port for specific CPU namespace SST { // SST Event facilities ------------------------------------------------------ //! signal of SST event using Signal = std::uint16_t; struct Evt { Signal sig; }; // template for downcasting SST events to specific Evt "subclasses" template EVT_ const *evt_downcast(Evt const *e) { return reinterpret_cast(e); } // SST Task facilities ------------------------------------------------------- //! SST Task priority using TaskPrio = std::uint8_t; //! SST internal event-queue counter using QCtr = std::uint8_t; //! SST Task (a.k.a. "Active Object") class Task { private: Evt const **m_qBuf; //!< ring buffer for the queue QCtr m_end; //!< last index in the ring buffer QCtr m_head; //!< index for inserting events QCtr m_tail; //!< index for removing events QCtr m_nUsed; //!< # used entries currently in the queue #ifdef SST_PORT_TASK_ATTR SST_PORT_TASK_ATTR #endif public: void start( TaskPrio prio, Evt const **qBuf, QCtr qLen, Evt const * const ie); void post(Evt const * const e) noexcept; virtual void init(Evt const * const ie) = 0; virtual void dispatch(Evt const * const e) = 0; static LockKey lock(TaskPrio ceiling); static void unlock(LockKey key); static int run(void); #ifdef SST_PORT_TASK_OPER // additional Task operations needed by the specific SST port SST_PORT_TASK_OPER #endif }; // SST Time Event facilities ------------------------------------------------- //! SST internal time-event tick counter using TCtr = std::uint16_t; //! SST time event class class TimeEvt : public Evt { private: TimeEvt *m_next; //! link to next time event in a link-list Task *m_task; //! the owner task to post time event to TCtr m_ctr; //! time event down-counter TCtr m_interval; //! interval for periodic time event public: TimeEvt(Signal sig, Task *task); void arm(TCtr ctr, TCtr interval); bool disarm(void); static void tick(void); }; // SST Kernel facilities ----------------------------------------------------- void init(void); void start(void); void onStart(void); void onIdle(void); } // namespace SST // general convenience utilities --------------------------------------------- #ifndef ARRAY_NELEM //! convenience macro to provide the number of elements in the array a_ #define ARRAY_NELEM(a_) (sizeof(a_) / sizeof((a_)[0])) #endif /* ARRAY_NELEM */ #endif // SST_HPP_ ================================================ FILE: legacy/README.md ================================================ ## Brought to you by: [![Quantum Leaps](https://www.state-machine.com/attachments/logo_ql_400.png)](https://www.state-machine.com) --------------------------------------------------------------------- # Super-Simple Tasker version 1.0, July 2006 Super-Simple Tasker (SST) is a **preemptive, priority-based RTOS kernel** fully compatible with the requirements of Rate Monotonic Analysis/Scheduling (RMA/RMS). This sub-directory contains the origianl, historic SST article and code, as published in 2006. [![Build a Super-Simple Tasker Article](img/sst1_2006.png)](Super-Simple-Tasker.pdf) # Build a Super Simple Tasker ## Miro Samek and Robert Ward (July, 2006) ["Build a Super-Simple Tasker"](Super-Simple-Tasker.pdf) was a cover story article published originally in [Embedded Systems Design](https://www.embedded.com/embedded-systems-design-july-2006) magazine in July 2006. # Licensing The SST source code and examples are released under the terms of the permissive [MIT open source license](../LICENSE). Please note that the attribution clause in the MIT license requires you to preserve the original copyright notice in all changes and derivate works. # Files and Directories The code repository the following subdirectories and files: ``` \ | +-README.md - this file | +-LICENSE - the GNU General Public License | +-example\ - subdirectory containing the SST example files | | | +-bin\ - contains .OBJ, .EXE, and .MAP files | +-bsp.c - Board Support Package for DOS/Turbo C++ 1.01 | +-bsp.h - BSP header file | +-kbd_task.c - The keyboard task function | +-main.c - The main function | +-sst_exa.h - The header file for the SST example application | +-sst_exa.prj - The Turbo C++ project file for building and | | debugging the SST example application from the | | Turbo C++ IDE | +-sst_port.h - SST port to DOS/Turbo C++ 1.01 | +-stdint.h - The C99 standard exact-width integer types | | for the Turbo C++ 1.01, which is a pre-standard | | compiler. You could copy this file to the | | Turbo C++ include directory. | +-tick_tsk.c - The two tick tasks (tickTaskA and tickTaskB) | +-include\ - subdirectory containing the SST public interface | +-sst.h - The platform-independent SST header file | +-source\ - subdirectory containing the SST implementation +-sst.c - platform-independent SST implementation ``` # Running the SST Example ![SST Running in DOS Window](img/sst1_fig05.png) The executable file for the SST example is provided in \example\bin\sst_exa.exe. You can run this executable on a Windows-based PC in a DOS emulator (e.g. DOSBox DOS emulator). > NOTE: The legacy DOS platform has been chosen for demonstrating SST, because it still allows programming with interrupts, directly manipulating CPU registers, and directly accessing I/O space of the processor (required for writing the EOI command to the 8259A interrupt controller). No other modern desktop development environment for the commodity PC allows this much so easily. The ubiquitous PC running under DOS (or a DOS emulator within any variant of Windows) is capable of demonstrating most key embedded features of SST. The example program takes one command-line argument, which is the number of iterations through a delay loop peppered throughout the application code. The purpose of this delay is to extend the run-to-completion processing (which is really short on the fast modern PCs), and thus increase the probability of asynchronous preemptions. We’ve been using a typical value of this delay around 10000 on a modern 2GHz PC, which corresponds to the following invocation of the SST example application: `sst_exa.exe 10000` As described in the article, you should not go overboard with this parameter because you can eventually overload the machine, and the SST will start losing events (the queues will overflow and won’t accept new events). Once the application starts running, you can generate asynchronous preemptions by typing on the keyboard. The keyboard interrupt is asynchronous with respect to the periodic time-tick interrupt and consequently the keyboard interrupt can preempt the time tick tasks (that run just after the tick interrupt), and the time tick interrupt can preempt the keyboard task (that runs just after the keyboard interrupt). Moreover, the interrupts can also preempt each other. Please note, however, that the tick ISR has the highest priority, and consequently the Programmable Interrupt Controller (the 8259A chip) will not allow in hardware that the lower-priority keyboard ISR preempts the highest-priority tick ISR. The only allowed interrupt preemption is that tick ISR preempts the keyboard ISR. You should verify this by observing the “Preemptions” column of the application display. After typing for a while on the keyboard, you should see some cases of the asynchronous preemption in the “Preemptions” column. The synchronous preemptions are not displayed, but they occur every time a keyboard task posts an event to the higher-priority tickTaskB(). On the other hand, the synchronous preemption does not occur when the keyboard task posts an event to the lower-priority tickTaskA(). # Legacy DOS Compiler In order to modify and recompile the example, you need to download and install a legacy DOS compiler, such as Turbo C++ 1.01, which is available for a free download from the Borland Museum at http://bdn.borland.com/article/0,1410,21751,00.html. To install Borland Turbo C++ 1.01, download the file TCPP101.ZIP from the Borland Museum and unzip it into a temporary directory. Run the INSTALL.EXE program and follow the installation instructions. Miro Samek
April 24, 2006 # Updates and Support for Modern Microcontrollers As described in the article, SST-type kernel is ideal for deterministic Run-To-Completion (RTC) execution of concurrent state machines. The website https://www.state-machine.com provides an implementation of the RTC kernel, called **QK** ("Quantum Kernel") that works exactly like SST and only differs in the way it is integrated with the [QP Real-Time Embedded Frameworks (RTEFs)](https://www.state-machine.com/products). QK has been ported to many embedded CPUs, such as: **ARM Cortex-M** (M0-M7), MSP430, PIC24/dsPIC, PIC32, etc.
October 14, 2011 ================================================ FILE: legacy/example/STDINT.H ================================================ /* stdint.h WG14/N843 C99 Standard, Section 7.18 This header is part of the ANSI C99 standard library. It describes a number of useful integer types. This file is not part of the original Borland Turbo C++ 1.01 distribution, which preceded the C99 standard. Currently, this file contains only the exact-width integer types and constants (see C99 Section 7.18.1.1) */ #ifndef __STDINT_H #define __STDINT_H #ifdef __cplusplus extern "C" { #endif /* Exact-width types. WG14/N843 C99 Standard, Section 7.18.1.1 */ typedef signed char int8_t; typedef signed int int16_t; typedef signed long int32_t; typedef unsigned char uint8_t; typedef unsigned int uint16_t; typedef unsigned long uint32_t; #ifdef __cplusplus } #endif #endif ================================================ FILE: legacy/example/bsp.c ================================================ /***************************************************************************** * Product: SST example, 80x86, Turbo C++ 1.01 * * Copyright (C) 2006 Miro Samek and Robert Ward. All rights reserved. * * MIT License * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *****************************************************************************/ #include "sst_port.h" #include "sst_exa.h" #include "bsp.h" #include /* for _exit() */ /* Local-scope objects -----------------------------------------------------*/ static void interrupt (*l_dosTickISR)(); static void interrupt (*l_dosKbdISR)(); #define TICKS_PER_SEC 200 #define TICK_VECTOR 0x08 #define KBD_VECTOR 0x09 static void displayPreemptions(uint8_t pprev, uint8_t pnext); /*..........................................................................*/ static void interrupt tickISR() { uint8_t pin; displayPreemptions(SST_currPrio_, TICK_ISR_PRIO);/* for testing, NOTE01 */ SST_ISR_ENTRY(pin, TICK_ISR_PRIO); SST_post(TICK_TASK_A_PRIO, TICK_SIG, 0); /* post the Tick to Task A */ SST_post(TICK_TASK_B_PRIO, TICK_SIG, 0); /* post the Tick to Task B */ busyDelay(); /* for testing, see NOTE02 */ SST_ISR_EXIT(pin, outportb(0x20, 0x20)); } /*..........................................................................*/ static void interrupt kbdISR() { uint8_t pin; uint8_t key = inport(0x60);/*get scan code from the 8042 kbd controller */ displayPreemptions(SST_currPrio_, KBD_ISR_PRIO); /* for testing, NOTE01 */ SST_ISR_ENTRY(pin, KBD_ISR_PRIO); SST_post(KBD_TASK_PRIO, KBD_SIG, key); /* post the Key to the KbdTask */ busyDelay(); /* for testing, see NOTE02 */ SST_ISR_EXIT(pin, outportb(0x20, 0x20)); } /*..........................................................................*/ void SST_init(void) { } /*..........................................................................*/ void SST_start(void) { /* divisor for the 8254 timer/counter */ uint16_t count = (uint16_t)(((1193180 * 2) / TICKS_PER_SEC + 1) >> 1); /* save the original DOS vectors ... */ l_dosTickISR = getvect(TICK_VECTOR); l_dosKbdISR = getvect(KBD_VECTOR); SST_INT_LOCK(); /* lock the interrupts */ outportb(0x43, 0x36); /* use mode-3 for timer 0 in the 8254 */ outportb(0x40, count & 0xFF); /* load low byte of timer 0 */ outportb(0x40, (count >> 8) & 0xFF); /* load high byte of timer 0 */ setvect(TICK_VECTOR, &tickISR); setvect(KBD_VECTOR, &kbdISR); SST_INT_UNLOCK(); /* unlock the interrupts */ } /*..........................................................................*/ void SST_onIdle(void) { static uint32_t onIdleCtr; Video_printNumAt(22, 19, VIDEO_FGND_YELLOW, ++onIdleCtr); } /*..........................................................................*/ void SST_exit(void) { SST_INT_LOCK(); /* lock the interrupts */ outportb(0x43, 0x36); /* use mode-3 for timer 0 in the 8254 */ outportb(0x40, 0); /* load low byte of timer 0 */ outportb(0x40, 0); /* load high byte of timer 0 */ /* restore the original DOS vectors ... */ setvect(TICK_VECTOR, l_dosTickISR); setvect(KBD_VECTOR, l_dosKbdISR); SST_INT_UNLOCK(); /* unlock the interrupts */ _exit(0); /* exit to DOS */ } /*--------------------------------------------------------------------------*/ void displayPreemptions(uint8_t pprev, uint8_t pnext) { if (pnext == TICK_ISR_PRIO) { static uint32_t tmrIsrCtr; /* timer interrupt counter */ Video_printNumAt(22, 7, VIDEO_FGND_YELLOW, ++tmrIsrCtr); } else if (pnext == KBD_ISR_PRIO) { static uint32_t kbdIsrCtr; /* kbd interrupt counter */ Video_printNumAt(22, 8, VIDEO_FGND_YELLOW, ++kbdIsrCtr); } if (pprev == TICK_ISR_PRIO) { /* is this Tick ISR preemption? */ static uint32_t tickPreCtr; /* Tick ISR preemption counter */ Video_printNumAt(30, 7, VIDEO_FGND_YELLOW, ++tickPreCtr); } else if (pprev == KBD_ISR_PRIO) { /* is this kbd ISR preemption? */ static uint32_t kbdPreCtr; /* kbd ISR preemption counter */ Video_printNumAt(30, 8, VIDEO_FGND_YELLOW, ++kbdPreCtr); } else { /* must be a task preemption */ static uint32_t preCtr[SST_MAX_PRIO + 2]; Video_printNumAt(30, 19 - pprev, VIDEO_FGND_YELLOW, ++preCtr[pprev]); } } /*--------------------------------------------------------------------------*/ void Video_clearScreen(uint8_t bgColor) { clrscr(); Video_clearRect(0, 0, 80, 25, bgColor); } /*..........................................................................*/ void Video_clearRect(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t bgColor) { for ( ; y1 < y2; ++y1) { uint8_t x; uint8_t far *pscr = (uint8_t far *)MK_FP(0xB800, (uint16_t)(((y1 * 80) + x1) * 2)); for (x = x1; x < x2; ++x) { pscr[0] = ' '; /* Put space in the video RAM */ pscr[1] = bgColor; /* Put video attribute in the video RAM */ pscr += 2; } } } /*..........................................................................*/ void Video_printChAt(uint8_t x, uint8_t y, uint8_t color, char ch) { /* calculate position on the video RAM (VGA) */ uint8_t far *pscr = (uint8_t far *)MK_FP(0xB800, (uint16_t)(((y * 80) + x) * 2)); pscr[0] = ch; pscr[1] = color; } /*..........................................................................*/ void Video_printStrAt(uint8_t x, uint8_t y, uint8_t color, char const *str) { /* calculate position on the video RAM (VGA) */ uint8_t far *pscr = (uint8_t far *)MK_FP(0xB800, (uint16_t)(((y * 80) + x) * 2)); while (*str != (uint8_t)0) { pscr[0] = *str++; /* Put character in video RAM */ pscr[1] |= color; /* Put video attribute in video RAM */ pscr += 2; } } /*..........................................................................*/ void Video_printNumAt(uint8_t x, uint8_t y, uint8_t color, uint32_t num) { char buf[4]; buf[3] = (char)0; buf[2] = (char)('0' + num % 10); num /= 10; buf[1] = (char)('0' + num % 10); num /= 10; buf[0] = (char)('0' + num % 10); if (buf[0] == '0') { buf[0] = ' '; } Video_printStrAt(x, y, color, buf); } /***************************************************************************** * NOTE01: * The function call to displayPreemptions() is added only to monitor the * "asynchronous" preemptions within the SST. * * NOTE02: * The call to busyDelay() is added only to extend the execution time * to increase the chance of an "asynchronous" preemption. */ ================================================ FILE: legacy/example/bsp.h ================================================ /***************************************************************************** * Product: SST example, 80x86, Turbo C++ 1.01 * * Copyright (C) 2006 Miro Samek and Robert Ward. All rights reserved. * * MIT License * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *****************************************************************************/ #ifndef bsp_h #define bsp_h /* Direct Video Access .....................................................*/ enum VideoColor { /* foreground */ VIDEO_FGND_BLACK = 0x00, VIDEO_FGND_BLUE = 0x01, VIDEO_FGND_GREEN = 0x02, VIDEO_FGND_CYAN = 0x03, VIDEO_FGND_RED = 0x04, VIDEO_FGND_PURPLE = 0x05, VIDEO_FGND_BROWN = 0x06, VIDEO_FGND_LIGHT_GRAY = 0x07, VIDEO_FGND_DARK_GRAY = 0x08, VIDEO_FGND_LIGHT_BLUE = 0x09, VIDEO_FGND_LIGHT_GREEN = 0x0A, VIDEO_FGND_LIGHT_CYAN = 0x0B, VIDEO_FGND_LIGHT_RED = 0x0C, VIDEO_FGND_LIGHT_PURPLE = 0x0D, VIDEO_FGND_YELLOW = 0x0E, VIDEO_FGND_WHITE = 0x0F, /* background */ VIDEO_BGND_BLACK = 0x00, VIDEO_BGND_BLUE = 0x10, VIDEO_BGND_GREEN = 0x20, VIDEO_BGND_CYAN = 0x30, VIDEO_BGND_RED = 0x40, VIDEO_BGND_PURPLE = 0x50, VIDEO_BGND_BROWN = 0x60, VIDEO_BGND_LIGHT_GRAY = 0x70, VIDEO_BGND_BLINK = 0x80 }; /*..........................................................................*/ void Video_clearScreen(uint8_t bgColor); void Video_clearRect(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t bgColor); void Video_printChAt(uint8_t x, uint8_t y, uint8_t color, char ch); void Video_printStrAt(uint8_t x, uint8_t y, uint8_t color, char const *str); void Video_printNumAt(uint8_t x, uint8_t y, uint8_t color, uint32_t num); #endif /* bsp_h */ ================================================ FILE: legacy/example/kbd_tsk.c ================================================ /***************************************************************************** * Product: SST example, 80x86, Turbo C++ 1.01 * * Copyright (C) 2006 Miro Samek and Robert Ward. All rights reserved. * * MIT License * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *****************************************************************************/ #include "sst_port.h" #include "sst_exa.h" #include "bsp.h" /*..........................................................................*/ void kbdTask(SSTEvent e) { static uint32_t kbdTaskCtr; Video_printNumAt(22, 19 - KBD_TASK_PRIO, VIDEO_FGND_YELLOW, ++kbdTaskCtr); busyDelay(); /* for testing, NOTE01 */ switch (e.sig) { case INIT_SIG: { Video_printStrAt( 1, 19 - KBD_TASK_PRIO, VIDEO_FGND_WHITE, "kbdTask"); break; } case KBD_SIG: { if (e.par == (SSTParam)0x81) { /* is this the ESC key? */ SST_exit(); } else if ((e.par & 1) != 0) { /* pick one of the Tick Tasks */ SST_post(TICK_TASK_A_PRIO, /* no synchronous preemption */ COLOR_SIG, e.par & 0xF); } else { SST_post(TICK_TASK_B_PRIO, /* synchronous preemption */ COLOR_SIG, (e.par & 0xF)); } break; } } } /***************************************************************************** * NOTE01: * The call to busyDelay() is added only to extend the execution time * to increase the chance of an "asynchronous" preemption. */ ================================================ FILE: legacy/example/main.c ================================================ /***************************************************************************** * Product: SST example, 80x86, Turbo C++ 1.01 * * Copyright (C) 2006 Miro Samek and Robert Ward. All rights reserved. * * MIT License * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *****************************************************************************/ #include "sst_port.h" #include "sst_exa.h" #include "bsp.h" #include /* for atol() */ static void setupScreen(void); static SSTEvent tickTaskAQueue[2]; static SSTEvent tickTaskBQueue[2]; static SSTEvent kbdTaskQueue[2]; static uint32_t l_delayCtr = 0UL; /*..........................................................................*/ int main(int argc, char *argv[]) { if (argc > 1) { /* delay specified? */ l_delayCtr = atol(argv[1]); } setupScreen(); /* setup the screen */ SST_init(); /* initialize the SST */ SST_task(&tickTaskA, TICK_TASK_A_PRIO, tickTaskAQueue, sizeof(tickTaskAQueue)/sizeof(tickTaskAQueue[0]), INIT_SIG, 0); SST_task(&tickTaskB, TICK_TASK_B_PRIO, tickTaskBQueue, sizeof(tickTaskBQueue)/sizeof(tickTaskBQueue[0]), INIT_SIG, 0); SST_task(&kbdTask, KBD_TASK_PRIO, kbdTaskQueue, sizeof(kbdTaskQueue)/sizeof(kbdTaskQueue[0]), INIT_SIG, 0); SST_run(); /* run the SST application */ return 0; } /*..........................................................................*/ static void setupScreen(void) { Video_clearScreen(VIDEO_BGND_BLACK); Video_clearRect( 0, 5, 80, 6, VIDEO_BGND_LIGHT_GRAY); Video_clearRect( 0, 6, 40, 23, VIDEO_BGND_BLUE); Video_clearRect(40, 6, 80, 23, VIDEO_BGND_RED); Video_clearRect(43, 8, 77, 21, VIDEO_BGND_BLACK); Video_clearRect( 0, 23, 80, 24, VIDEO_BGND_LIGHT_GRAY); Video_printStrAt(31, 2, VIDEO_FGND_YELLOW, "Super Simple Tasker"); Video_printStrAt( 0, 5, VIDEO_FGND_BLUE, " Task Priority Calls Preemptions"); Video_printStrAt( 1, 7, VIDEO_FGND_WHITE, "tickISR 255"); Video_printStrAt( 1, 8, VIDEO_FGND_WHITE, "kbdISR 254"); Video_printStrAt( 1, 10, VIDEO_FGND_WHITE, "schedLock 9"); Video_printStrAt( 1, 11, VIDEO_FGND_WHITE, "task8 8"); Video_printStrAt( 1, 12, VIDEO_FGND_WHITE, "task7 7"); Video_printStrAt( 1, 13, VIDEO_FGND_WHITE, "task6 6"); Video_printStrAt( 1, 14, VIDEO_FGND_WHITE, "task5 5"); Video_printStrAt( 1, 15, VIDEO_FGND_WHITE, "task4 4"); Video_printStrAt( 1, 16, VIDEO_FGND_WHITE, "task3 3"); Video_printStrAt( 1, 17, VIDEO_FGND_WHITE, "task2 2"); Video_printStrAt( 1, 18, VIDEO_FGND_WHITE, "task1 1"); Video_printStrAt( 1, 19, VIDEO_FGND_WHITE, "idle Loop 0"); Video_printStrAt(4, 23, VIDEO_FGND_BLUE, "* Copyright (c) 2006 Quantum Leaps, LLC " "* www.quantum-leaps.com *"); Video_printStrAt(28, 24, VIDEO_FGND_LIGHT_RED, "<< Press Esc to quit >>"); } /*..........................................................................*/ void busyDelay(void) { volatile uint32_t i = l_delayCtr; while (i-- > 0) { } } ================================================ FILE: legacy/example/sst_exa.h ================================================ /***************************************************************************** * Product: SST example, 80x86, Turbo C++ 1.01 * * Copyright (C) 2006 Miro Samek and Robert Ward. All rights reserved. * * MIT License * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *****************************************************************************/ #ifndef sst_exa_h #define sst_exa_h void tickTaskA(SSTEvent e); void tickTaskB(SSTEvent e); void kbdTask(SSTEvent e); enum Events { /* the events used in the application */ INIT_SIG, /* initialization event */ TICK_SIG, KBD_SIG, COLOR_SIG }; enum SSTPriorities { /* the SST priorities don't need to be consecutive */ /* task priorities... */ TICK_TASK_A_PRIO = 2, KBD_TASK_PRIO = 5, TICK_TASK_B_PRIO = 7, /* ISR priorities... */ KBD_ISR_PRIO = 0xFF - 1, TICK_ISR_PRIO = 0xFF }; #endif /* sst_exa_h */ ================================================ FILE: legacy/example/sst_port.h ================================================ /***************************************************************************** * Product: SST example, 80x86, Turbo C++ 1.01 * * Copyright (C) 2006 Miro Samek and Robert Ward. All rights reserved. * * MIT License * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *****************************************************************************/ #ifndef sst_port_h #define sst_port_h /* SST interrupt locking/unlocking */ #define SST_INT_LOCK() disable() #define SST_INT_UNLOCK() enable() /* maximum SST task priority */ #define SST_MAX_PRIO 8 #include /* for declarations of disable()/enable() */ #undef outportb /*don't use the macro because it has a bug in Turbo C++ 1.01*/ #include "sst.h" /* SST platform-independent interface */ #endif /* sst_port_h */ ================================================ FILE: legacy/example/tick_tsk.c ================================================ /***************************************************************************** * Product: SST example, 80x86, Turbo C++ 1.01 * * Copyright (C) 2006 Miro Samek and Robert Ward. All rights reserved. * * MIT License * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *****************************************************************************/ #include "sst_port.h" #include "sst_exa.h" #include "bsp.h" #include /* for random() */ /*..........................................................................*/ void tickTaskA(SSTEvent e) { static uint32_t tickTaskACtr; static uint8_t colorA = VIDEO_BGND_LIGHT_GRAY; Video_printNumAt(22, 19 - TICK_TASK_A_PRIO, VIDEO_FGND_YELLOW, ++tickTaskACtr); busyDelay(); /* for testing, NOTE01 */ switch (e.sig) { case INIT_SIG: { Video_printStrAt( 1, 19 - TICK_TASK_A_PRIO, VIDEO_FGND_WHITE, "tickTaskA"); break; } case TICK_SIG: { uint8_t x, y; uint8_t mutex; mutex = SST_mutexLock(TICK_TASK_B_PRIO); /* the other tick task */ x = random(34); y = random(13); SST_mutexUnlock(mutex); Video_printChAt(x + 43, y + 8, colorA, 'A'); break; } case COLOR_SIG: { colorA = e.par; /* color is delivered in the parameter */ break; } } } /*..........................................................................*/ void tickTaskB(SSTEvent e) { static uint32_t tickTaskBCtr; static uint8_t colorB = VIDEO_BGND_LIGHT_GRAY; Video_printNumAt(22, 19 - TICK_TASK_B_PRIO, VIDEO_FGND_YELLOW, ++tickTaskBCtr); busyDelay(); /* for testing, NOTE01 */ switch (e.sig) { case INIT_SIG: { Video_printStrAt( 1, 19 - TICK_TASK_B_PRIO, VIDEO_FGND_WHITE, "tickTaskB"); break; } case TICK_SIG: { uint8_t x, y; uint8_t mutex; mutex = SST_mutexLock(TICK_TASK_A_PRIO); /* the other tick task */ x = random(34); y = random(13); SST_mutexUnlock(mutex); Video_printChAt(x + 43, y + 8, colorB, 'B'); break; } case COLOR_SIG: { colorB = e.par; /* color is delivered in the parameter */ break; } } } /***************************************************************************** * NOTE01: * The call to busyDelay() is added only to extend the execution time * to increase the chance of an "asynchronous" preemption. */ ================================================ FILE: legacy/include/sst.h ================================================ /***************************************************************************** * SST platform-independent public interface * * Copyright (C) 2006 Miro Samek and Robert Ward. All rights reserved. * * MIT License * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *****************************************************************************/ #ifndef sst_h #define sst_h #include /* exact-width integer types, ANSI C'99 */ typedef uint8_t SSTSignal; typedef uint8_t SSTParam; typedef struct SSTEventTag SSTEvent; struct SSTEventTag { SSTSignal sig; SSTParam par; }; typedef void (*SSTTask)(SSTEvent e); void SST_init(void); void SST_task(SSTTask task, uint8_t prio, SSTEvent *queue, uint8_t qlen, SSTSignal sig, SSTParam par); void SST_start(void); void SST_run(void); void SST_onIdle(void); void SST_exit(void); uint8_t SST_post(uint8_t prio, SSTSignal sig, SSTParam par); uint8_t SST_mutexLock(uint8_t prioCeiling); void SST_mutexUnlock(uint8_t orgPrio); void SST_schedule_(void); /* SST interrupt entry and exit */ #define SST_ISR_ENTRY(pin_, isrPrio_) do { \ (pin_) = SST_currPrio_; \ SST_currPrio_ = (isrPrio_); \ SST_INT_UNLOCK(); \ } while (0) #define SST_ISR_EXIT(pin_, EOI_command_) do { \ SST_INT_LOCK(); \ (EOI_command_); \ SST_currPrio_ = (pin_); \ SST_schedule_(); \ } while (0) /* public-scope objects */ extern uint8_t SST_currPrio_; /* current priority of the executing task */ extern uint8_t SST_readySet_; /* SST ready-set */ #endif /* sst_h */ ================================================ FILE: legacy/source/sst.c ================================================ /***************************************************************************** * SST platform-independent implementation * * Copyright (C) 2006 Miro Samek and Robert Ward. All rights reserved. * * MIT License * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *****************************************************************************/ #include "sst_port.h" /* Public-scope objects ----------------------------------------------------*/ uint8_t SST_currPrio_ = (uint8_t)0xFF; /* current SST priority */ uint8_t SST_readySet_ = (uint8_t)0; /* SST ready-set */ typedef struct TaskCBTag TaskCB; struct TaskCBTag { SSTTask task__; SSTEvent *queue__; uint8_t end__; uint8_t head__; uint8_t tail__; uint8_t nUsed__; uint8_t mask__; }; /* Local-scope objects -----------------------------------------------------*/ static TaskCB l_taskCB[SST_MAX_PRIO]; /*..........................................................................*/ void SST_task(SSTTask task, uint8_t prio, SSTEvent *queue, uint8_t qlen, SSTSignal sig, SSTParam par) { SSTEvent ie; /* initialization event */ TaskCB *tcb = &l_taskCB[prio - 1]; tcb->task__ = task; tcb->queue__ = queue; tcb->end__ = qlen; tcb->head__ = (uint8_t)0; tcb->tail__ = (uint8_t)0; tcb->nUsed__ = (uint8_t)0; tcb->mask__ = (1 << (prio - 1)); ie.sig = sig; ie.par = par; tcb->task__(ie); /* initialize the task */ } /*..........................................................................*/ void SST_run(void) { SST_start(); /* start ISRs */ SST_INT_LOCK(); SST_currPrio_ = (uint8_t)0; /* set the priority for the SST idle loop */ SST_schedule_(); /* process all events produced so far */ SST_INT_UNLOCK(); for (;;) { /* the SST idle loop */ SST_onIdle(); /* invoke the on-idle callback */ } } /*..........................................................................*/ uint8_t SST_post(uint8_t prio, SSTSignal sig, SSTParam par) { TaskCB *tcb = &l_taskCB[prio - 1]; SST_INT_LOCK(); if (tcb->nUsed__ < tcb->end__) { tcb->queue__[tcb->head__].sig = sig;/* insert the event at the head */ tcb->queue__[tcb->head__].par = par; if ((++tcb->head__) == tcb->end__) { tcb->head__ = (uint8_t)0; /* wrap the head */ } if ((++tcb->nUsed__) == (uint8_t)1) { /* the first event? */ SST_readySet_ |= tcb->mask__; /* insert task to the ready set */ SST_schedule_(); /* check for synchronous preemption */ } SST_INT_UNLOCK(); return (uint8_t)1; /* event successfully posted */ } else { SST_INT_UNLOCK(); return (uint8_t)0; /* queue full, event posting failed */ } } /*..........................................................................*/ uint8_t SST_mutexLock(uint8_t prioCeiling) { uint8_t p; SST_INT_LOCK(); p = SST_currPrio_; /* the original SST priority to return */ if (prioCeiling > SST_currPrio_) { SST_currPrio_ = prioCeiling; /* raise the SST priority */ } SST_INT_UNLOCK(); return p; } /*..........................................................................*/ void SST_mutexUnlock(uint8_t orgPrio) { SST_INT_LOCK(); if (orgPrio < SST_currPrio_) { SST_currPrio_ = orgPrio; /* restore the saved priority to unlock */ SST_schedule_(); /* the scheduler unlocks the interrupts internally */ } SST_INT_UNLOCK(); } /*..........................................................................*/ /* NOTE: the SST scheduler is entered and exited with interrupts LOCKED */ void SST_schedule_(void) { static uint8_t const log2Lkup[] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }; uint8_t pin = SST_currPrio_; /* save the initial priority */ uint8_t p; /* the new priority */ /* is the new priority higher than the initial? */ while ((p = log2Lkup[SST_readySet_]) > pin) { TaskCB *tcb = &l_taskCB[p - 1]; /* get the event out of the queue */ SSTEvent e = tcb->queue__[tcb->tail__]; if ((++tcb->tail__) == tcb->end__) { tcb->tail__ = (uint8_t)0; } if ((--tcb->nUsed__) == (uint8_t)0) {/* is the queue becoming empty?*/ SST_readySet_ &= ~tcb->mask__; /* remove from the ready set */ } SST_currPrio_ = p; /* this becomes the current task priority */ SST_INT_UNLOCK(); /* unlock the interrupts */ (*tcb->task__)(e); /* call the SST task */ SST_INT_LOCK(); /* lock the interrupts for the next pass */ } SST_currPrio_ = pin; /* restore the initial priority */ } ================================================ FILE: sst0_c/README.txt ================================================ This directory contains the non-preemptive SST implementation in C, referred to as "SST0/C". - "basic tasks" (non-blocking) - preemptive scheduling - multiple tasks per prioriy level - multiple "activations" per task (event queues) ================================================ FILE: sst0_c/examples/README.txt ================================================ This directory contains examples for the non-preemptive SST0/C kernel. ================================================ FILE: sst0_c/examples/blinky/armclang/nucleo-l053r8.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 nucleo-l053r8 0x4 ARM-ADS 12000000 1 1 0 1 0 1 65535 0 0 0 79 66 8 .\build_nucleo-l053r8\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 UL2CM3 UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM)) 0 ST-LINKIII-KEIL_SWO -U066CFF484951775087074312 -O8431 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P2 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC800 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=1702,853,2113,1355,0)(1007=2082,245,2289,466,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS 0 0 188 1
0
0 0 0 0 0 0 ..\bsp_nucleo-l053r8.c
1 0 200 1
0
0 0 0 0 0 0 ..\bsp_nucleo-l053r8.c
1 2 0xE000E400 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 10000000
Application 1 0 0 0 1 1 5 0 0 0 ..\bsp.h bsp.h 0 0 1 2 1 0 0 0 ..\bsp_nucleo-l053r8.c bsp_nucleo-l053r8.c 0 0 1 3 1 0 0 0 ..\main.c main.c 0 0 1 4 1 0 0 0 ..\blinky.c blinky.c 0 0 1 5 5 0 0 0 ..\blinky.h blinky.h 0 0 nucleo-l053r8 1 0 0 0 2 6 2 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s startup_stm32l053xx.s 0 0 2 7 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l0xx.h 0 0 2 8 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h stm32l053xx.h 0 0 2 9 1 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c system_stm32l0xx.c 0 0 sst 1 0 0 0 3 10 1 0 0 0 ..\..\..\src\sst0.c sst0.c 0 0 sst_port 1 0 0 0 4 11 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.h sst_port.h 0 0
================================================ FILE: sst0_c/examples/blinky/armclang/nucleo-l053r8.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
nucleo-l053r8 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32L053R8Tx STMicroelectronics Keil.STM32L0xx_DFP.2.2.0 http://www.keil.com/pack/ IRAM(0x20000000,0x00002000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$Flash\STM32L0xx_64.FLM)) 0 $$Device:STM32L053R8Tx$Device\Include\stm32l0xx.h $$Device:STM32L053R8Tx$SVD\STM32L053x.svd 0 0 0 0 0 0 1 .\build_nucleo-l053r8\ blinky_button 1 0 0 1 1 .\build_nucleo-l053r8\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-l053r8\blinky_button.bin .\build_nucleo-l053r8\blinky_button.axf 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP DARMCM1.DLL -pCM0+ SARMCM3.DLL TARMCM1.DLL -pCM0+ 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M0+" 0 0 0 1 1 0 0 0 0 0 0 0 8 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 1 0x8000000 0x10000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x10000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 0 0x0 0x0 0 0 0 0 1 0 0 0 0 0 4 0 1 0 0 0 3 3 0 0 0 0 0 -Wno-padded .;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-l053r8 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Application bsp.h 5 ..\bsp.h bsp_nucleo-l053r8.c 1 ..\bsp_nucleo-l053r8.c main.c 1 ..\main.c blinky.c 1 ..\blinky.c blinky.h 5 ..\blinky.h nucleo-l053r8 startup_stm32l053xx.s 2 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s stm32l0xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l053xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h system_stm32l0xx.c 1 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c sst sst0.c 1 ..\..\..\src\sst0.c sst_port sst_port.h 5 ..\..\..\ports\arm-cm\sst_port.h nucleo-l053r8 1
================================================ FILE: sst0_c/examples/blinky/blinky.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky.h" /* application shared interface */ DBC_MODULE_NAME("blinky") /* for DBC assertions in this module */ /* Blinky event-driven task ------------------------------------------------*/ typedef struct { SST_Task super; /* inherit SST_Task */ SST_TimeEvt te1; SST_TimeEvt te2; } Blinky; static void Blinky_ctor(Blinky * const me); static void Blinky_init(Blinky * const me, SST_Evt const * const ie); static void Blinky_dispatch(Blinky * const me, SST_Evt const * const e); /*..........................................................................*/ static Blinky Blinky_inst; /* the Blinky instance */ SST_Task * const AO_Blinky = &Blinky_inst.super; /* opaque AO pointer */ /*..........................................................................*/ void Blinky_instantiate(void) { Blinky_ctor(&Blinky_inst); } /*..........................................................................*/ void Blinky_ctor(Blinky * const me) { SST_Task_ctor( &me->super, (SST_Handler)&Blinky_init, (SST_Handler)&Blinky_dispatch); SST_TimeEvt_ctor(&me->te1, TIMEOUT1_SIG, &me->super); SST_TimeEvt_ctor(&me->te2, TIMEOUT2_SIG, &me->super); } /* macro to select the Blinky implementation */ #define BLINKY_IMPL 2 /*--------------------------------------------------------------------------*/ #if BLINKY_IMPL == 1 /* Blinky implementation closest matching the traditional blocking approach */ static void Blinky_init(Blinky * const me, SST_Evt const * const ie) { (void)ie; /* unused parameter */ SST_TimeEvt_arm(&me->te1, 1U, 0U); } /*..........................................................................*/ static void Blinky_dispatch(Blinky * const me, SST_Evt const * const e) { switch (e->sig) { case TIMEOUT1_SIG: { BSP_ledOn(); SST_TimeEvt_arm(&me->te2, BSP_TICKS_PER_SEC / 4U, 0U); break; } case TIMEOUT2_SIG: { BSP_ledOff(); SST_TimeEvt_arm(&me->te1, BSP_TICKS_PER_SEC * 3U/4U, 0U); break; } default: { DBC_ERROR(200); break; } } } /*--------------------------------------------------------------------------*/ #elif BLINKY_IMPL == 2 /* Blinky implementation with two periodic time events with offset */ static void Blinky_init(Blinky * const me, SST_Evt const * const ie) { (void)ie; /* unused parameter */ SST_TimeEvt_arm(&me->te1, 1U, BSP_TICKS_PER_SEC); SST_TimeEvt_arm(&me->te2, 1U + (BSP_TICKS_PER_SEC/4U), BSP_TICKS_PER_SEC); } /*..........................................................................*/ static void Blinky_dispatch(Blinky * const me, SST_Evt const * const e) { switch (e->sig) { case TIMEOUT1_SIG: { BSP_ledOn(); break; } case TIMEOUT2_SIG: { BSP_ledOff(); break; } default: { DBC_ERROR(200); break; } } } /*--------------------------------------------------------------------------*/ #else #error "Wrong definition of the macro BLINKY_VERSION" #endif ================================================ FILE: sst0_c/examples/blinky/blinky.h ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #ifndef BLINKY_H_ #define BLINKY_H_ #include "dbc_assert.h" /* Design By Contract (DBC) assertions */ enum Signals { TIMEOUT1_SIG, TIMEOUT2_SIG, /* ... */ MAX_SIG /* the last signal */ }; void Blinky_instantiate(void); extern SST_Task * const AO_Blinky; /* opaque task pointer */ #endif /* BLINKY_H_ */ ================================================ FILE: sst0_c/examples/blinky/bsp.h ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #ifndef BSP_H_ #define BSP_H_ #define BSP_TICKS_PER_SEC 1000U void BSP_init(void); void BSP_ledOn(void); void BSP_ledOff(void); #endif /* BSP_H_ */ ================================================ FILE: sst0_c/examples/blinky/bsp_nucleo-l053r8.c ================================================ /*============================================================================ * Super-Simple Tasker (SST0/C) Example for STM32 NUCLEO-L053R8 * * Q u a n t u m L e a P s * ------------------------ * Modern Embedded Software * * Copyright (C) 2005 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" #include "bsp.h" #include "blinky.h" #include "stm32l0xx.h" /* CMSIS-compliant header file for the MCU used */ /* add other drivers if necessary... */ //DBC_MODULE_NAME("bsp_nucleo-l053r8") /* for DBC assertions in this module */ /* Local-scope defines -----------------------------------------------------*/ /* test pins on GPIO PA */ #define LED_PIN 5U /* LED LD2-Green */ /* ISRs used in the application ============================================*/ void SysTick_Handler(void); /* prototype */ void SysTick_Handler(void) { /* system clock tick ISR */ SST_TimeEvt_tick(); /* process all SST time events */ } /* Assertion handler ======================================================*/ DBC_NORETURN void DBC_fault_handler(char const * const module, int const label) { /* * NOTE: add here your application-specific error handling */ (void)module; (void)label; /* set PRIMASK to disable interrupts and stop SST right here */ __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { /* keep blinking LED2 */ BSP_ledOn(); /* turn LED2 on */ uint32_t volatile ctr; for (ctr = 10000U; ctr > 0U; --ctr) { } BSP_ledOff(); /* turn LED2 off */ for (ctr = 10000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } /*..........................................................................*/ void assert_failed(char const * const module, int const label);/* prototype */ void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } /* BSP functions ===========================================================*/ void BSP_init(void) { /* Configure the MPU to prevent NULL-pointer dereferencing * see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu */ MPU->RBAR = 0x0U /* base address (NULL) */ | MPU_RBAR_VALID_Msk /* valid region */ | (MPU_RBAR_REGION_Msk & 7U); /* region #7 */ MPU->RASR = (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1) region */ | (0x0U << MPU_RASR_AP_Pos) /* no-access region */ | MPU_RASR_ENABLE_Msk; /* region enable */ MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk /* enable background region */ | MPU_CTRL_ENABLE_Msk; /* enable the MPU */ __ISB(); __DSB(); /* enable GPIO port PA clock */ RCC->IOPENR |= (1U << 0U); /* set all used GPIOA pins as push-pull output, no pull-up, pull-down */ GPIOA->MODER &= ~(3U << 2U*LED_PIN); GPIOA->MODER |= (1U << 2U*LED_PIN); GPIOA->OTYPER &= ~(1U << LED_PIN); GPIOA->PUPDR &= ~(3U << 2U*LED_PIN); } /*..........................................................................*/ void BSP_ledOn(void) { GPIOA->BSRR = (1U << LED_PIN); } /* LED2 */ void BSP_ledOff(void) { GPIOA->BSRR = (1U << (LED_PIN + 16U)); } /* SST callbacks ===========================================================*/ void SST_onStart(void) { SystemCoreClockUpdate(); /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ SysTick_Config((SystemCoreClock / BSP_TICKS_PER_SEC) + 1U); /* set priorities of ISRs used in the system */ NVIC_SetPriority(SysTick_IRQn, 0U); /* ... */ } /*..........................................................................*/ void SST_onIdleCond(void) { /* NOTE: called with interrupts DISABLED */ #ifdef NDEBUG /* Put the CPU and peripherals to the low-power mode. * you might need to customize the clock management for your application, * see the datasheet for your particular Cortex-M MCU. */ __WFI(); /* Wait-For-Interrupt */ #endif SST_PORT_INT_ENABLE(); /* NOTE: enable interrupts for SS0 */ } ================================================ FILE: sst0_c/examples/blinky/gnu/nucleo-l053r8.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST0/C) on NUCLEO-L053R8, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-01-22 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f nucleo-l053r8.mak # make -f nucleo-l053r8.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky TARGET := nucleo-l053r8 #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ sst0.c \ main.c \ blinky.c \ bsp_nucleo-l053r8.c \ system_stm32l0xx.c \ startup_stm32l053xx.c # C++ source files CPP_SRCS := LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m0plus ARM_FPU := FLOAT_ABI := #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst0_c/examples/blinky/iar/nucleo-l053r8.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst0_c/examples/blinky/iar/nucleo-l053r8.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Debug Application $PROJ_DIR$\..\blinky.c $PROJ_DIR$\..\blinky.h $PROJ_DIR$\..\bsp.h $PROJ_DIR$\..\bsp_nucleo-l053r8.c $PROJ_DIR$\..\main.c nucleo-l053r8 $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\iar\startup_stm32l053xx.s $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c sst $PROJ_DIR$\..\..\..\src\sst0.c sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.h ================================================ FILE: sst0_c/examples/blinky/iar/nucleo-l053r8.eww ================================================ $WS_DIR$\nucleo-l053r8.ewp ================================================ FILE: sst0_c/examples/blinky/main.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky.h" /* application shared interface */ /*..........................................................................*/ int main() { SST_init(); /* initialize the SST kernel */ BSP_init(); /* initialize the Board Support Package */ /* instantiate and start all SST tasks... */ Blinky_instantiate(); static SST_Evt const *blinkyQSto[10]; /* Event queue storage */ SST_Task_start( AO_Blinky, /* AO pointer to start */ 1U, /* SST-priority */ blinkyQSto, /* storage for the AO's queue */ ARRAY_NELEM(blinkyQSto), /* queue length */ (void *)0); /* initialization event (not used) */ return SST_Task_run(); /* run the SST tasks */ /* NOTE; in embedded systems SST_Task_run() should not return */ } ================================================ FILE: sst0_c/examples/blinky_button/armclang/ek-tm4c123gxl.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 ek-tm4c123gxl 0x4 ARM-ADS 12000000 1 1 1 0 0 1 65535 0 0 0 79 66 8 .\build_ek-tm4c123gxl\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 4 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 0 0 19 BIN\lmidk-agdi.dll 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 UL2CM3 UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0TM4C123_256 -FL040000 -FS00 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM) 0 DLGTARM (1010=1120,219,1570,776,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=1881,651,2358,966,0) 0 ARMDBGFLAGS 0 lmidk-agdi -U0E10259B -O4686 -S5 -FO29 0 0 247 1
2900
0 0 0 0 0 1 ..\bsp_ek-tm4c123gxl.c \\build_ek_tm4c123gxl\../bsp_ek-tm4c123gxl.c\247
1 2 0x20000200 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Applicatioin 1 0 0 0 1 1 1 0 0 0 ..\main.c main.c 0 0 1 2 5 0 0 0 ..\blinky_button.h blinky_button.h 0 0 1 3 1 0 0 0 ..\blinky1.c blinky1.c 0 0 1 4 1 0 0 0 ..\blinky3.c blinky3.c 0 0 1 5 5 0 0 0 ..\bsp.h bsp.h 0 0 1 6 1 0 0 0 ..\bsp_ek-tm4c123gxl.c bsp_ek-tm4c123gxl.c 0 0 1 7 1 0 0 0 ..\button2a.c button2a.c 0 0 1 8 1 0 0 0 ..\button2b.c button2b.c 0 0 ek-tm4c123gxl 1 0 0 0 2 9 2 0 0 0 ..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s startup_TM4C123GH6PM.s 0 0 2 10 1 0 0 0 ..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c system_TM4C123GH6PM.c 0 0 2 11 5 0 0 0 ..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h TM4C123GH6PM.h 0 0 sst 1 0 0 0 3 12 1 0 0 0 ..\..\..\src\sst0.c sst0.c 0 0 sst_port 1 0 0 0 4 13 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.h sst_port.h 0 0
================================================ FILE: sst0_c/examples/blinky_button/armclang/ek-tm4c123gxl.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
ek-tm4c123gxl 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 TM4C123GH6PM Texas Instruments Keil.TM4C_DFP.1.1.0 http://www.keil.com/pack/ IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0TM4C123_256 -FS00 -FL040000 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM)) 0 $$Device:TM4C123GH6PM$Device\Include\TM4C123\TM4C123.h $$Device:TM4C123GH6PM$SVD\TM4C123\TM4C123GH6PM.svd 0 0 0 0 0 0 1 .\build_ek-tm4c123gxl\ blinky_button 1 0 0 1 1 .\build_ek-tm4c123gxl\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_ek-tm4c123gxl\blinky_button.bin .\build_ek-tm4c123gxl\blinky_button.axf 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -MPU DCM.DLL -pCM4 SARMCM3.DLL -MPU TCM.DLL -pCM4 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL "" () 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M4" 0 0 0 1 1 0 0 2 0 0 0 0 8 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x8000 1 0x0 0x40000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x40000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x8000 0 0x0 0x0 0 1 0 0 1 0 0 0 0 0 3 0 1 0 0 0 3 3 0 0 0 0 0 __FPU_PRESENT ..;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\ek-tm4c123gxl 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Applicatioin main.c 1 ..\main.c blinky_button.h 5 ..\blinky_button.h blinky1.c 1 ..\blinky1.c blinky3.c 1 ..\blinky3.c bsp.h 5 ..\bsp.h bsp_ek-tm4c123gxl.c 1 ..\bsp_ek-tm4c123gxl.c button2a.c 1 ..\button2a.c button2b.c 1 ..\button2b.c ek-tm4c123gxl startup_TM4C123GH6PM.s 2 ..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s system_TM4C123GH6PM.c 1 ..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c TM4C123GH6PM.h 5 ..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h sst sst0.c 1 ..\..\..\src\sst0.c sst_port sst_port.h 5 ..\..\..\ports\arm-cm\sst_port.h ek-tm4c123gxl 1
================================================ FILE: sst0_c/examples/blinky_button/armclang/nucleo-c031c6.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 nucleo-c031c6 0x4 ARM-ADS 12000000 1 1 0 1 0 1 65535 0 0 0 79 66 8 .\build_nucleo-c031c6\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 ST-LINKIII-KEIL_SWO -U-O206 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 UL2CM3 UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) 0 lmidk-agdi -U0E10259B -O4622 -S3 -FO29 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=1150,195,1600,752,0)(1007=-1,-1,-1,-1,0)(1008=1224,174,1600,410,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS 0 0 270 1
134217990
0 0 0 0 0 1 ..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s \\blinky_button\../../../../3rd_party/nucleo-c031c6/arm/startup_stm32c031xx.s\270
1 0 120 1
0
0 0 0 0 0 0 ..\bsp_nucleo-c031c6.c
0 1 OS_curr 1 1 OS_next 2 1 OS_readySet 1 2 0xE0001000 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 2 10000000
Application 1 0 0 0 1 1 1 0 0 0 ..\blinky1.c blinky1.c 0 0 1 2 1 0 0 0 ..\blinky3.c blinky3.c 0 0 1 3 5 0 0 0 ..\bsp.h bsp.h 0 0 1 4 1 0 0 0 ..\button2a.c button2a.c 0 0 1 5 1 0 0 0 ..\button2b.c button2b.c 0 0 1 6 1 0 0 0 ..\main.c main.c 0 0 1 7 1 0 0 0 ..\bsp_nucleo-c031c6.c bsp_nucleo-c031c6.c 0 0 nucleo-c031c6 1 0 0 0 2 8 5 0 0 0 ..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h stm32c031xx.h 0 0 2 9 1 0 0 0 ..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c system_stm32c0xx.c 0 0 2 10 2 0 0 0 ..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s startup_stm32c031xx.s 0 0 sst 1 0 0 0 3 11 1 0 0 0 ..\..\..\src\sst0.c sst0.c 0 0 sst_port 1 0 0 0 4 12 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.h sst_port.h 0 0
================================================ FILE: sst0_c/examples/blinky_button/armclang/nucleo-c031c6.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
nucleo-c031c6 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32C031C6Tx STMicroelectronics Keil.STM32C0xx_DFP.1.0.0 https://www.keil.com/pack/ IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) 0 $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd 0 0 0 0 0 0 1 .\build_nucleo-c031c6\ blinky_button 1 0 0 1 1 .\build_nucleo-c031c6\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-c031c6\blinky_button.bin .\build_nucleo-c031c6\blinky_button.axf 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP-MPU DARMCM1.DLL -pCM0+ SARMCM3.DLL -MPU TARMCM1.DLL -pCM0+ 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL "" () 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M0+" 0 0 0 1 1 0 0 0 0 0 0 0 8 1 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x3000 1 0x8000000 0x8000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x8000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x3000 0 0x0 0x0 0 0 0 0 1 0 0 0 0 0 3 0 1 1 0 0 3 3 0 0 0 0 0 -Wconditional-uninitialized -Wsometimes-uninitialized .;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-c031c6 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Application blinky1.c 1 ..\blinky1.c blinky3.c 1 ..\blinky3.c bsp.h 5 ..\bsp.h button2a.c 1 ..\button2a.c button2b.c 1 ..\button2b.c main.c 1 ..\main.c bsp_nucleo-c031c6.c 1 ..\bsp_nucleo-c031c6.c nucleo-c031c6 stm32c031xx.h 5 ..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h system_stm32c0xx.c 1 ..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c startup_stm32c031xx.s 2 ..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s sst sst0.c 1 ..\..\..\src\sst0.c sst_port sst_port.h 5 ..\..\..\ports\arm-cm\sst_port.h ek-tm4c123gxl 1
================================================ FILE: sst0_c/examples/blinky_button/armclang/nucleo-h743zi.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 arm-nucleo-h743zi 0x4 ARM-ADS 12000000 1 1 1 0 0 1 65535 0 0 0 79 66 8 .\build_nucleo-h743zi\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 0 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 UL2CM3 UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0STM32H7x_2048 -FL0200000 -FS08000000 -FP0($$Device:STM32H743ZITx$CMSIS\Flash\STM32H7x_2048.FLM) 0 ST-LINKIII-KEIL_SWO -U0675FF504955857567065746 -O8399 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P2 -N00("ARM CoreSight SW-DP (ARM Core") -D00(6BA02477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20010000 -FC1000 -FN1 -FF0STM32H7x_2048.FLM -FS08000000 -FL0200000 -FP0($$Device:STM32H743ZITx$CMSIS\Flash\STM32H7x_2048.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=1221,723,1671,1280,0)(6017=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(6016=-1,-1,-1,-1,0)(1012=3268,1338,3745,1653,0) 0 ARMDBGFLAGS 0 0 336 1
134220912
0 0 0 0 0 1 ..\bsp_nucleo-h743zi.c \\blinky_button\../bsp_nucleo-h743zi.c\336
0 1 nvic_prio_shift 1 2 0xE000ED08 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 10000000
Applicatioin 1 0 0 0 1 1 5 0 0 0 ..\blinky_button.h blinky_button.h 0 0 1 2 1 0 0 0 ..\blinky1.c blinky1.c 0 0 1 3 1 0 0 0 ..\blinky3.c blinky3.c 0 0 1 4 5 0 0 0 ..\bsp.h bsp.h 0 0 1 5 1 0 0 0 ..\bsp_nucleo-h743zi.c bsp_nucleo-h743zi.c 0 0 1 6 1 0 0 0 ..\button2a.c button2a.c 0 0 1 7 1 0 0 0 ..\button2b.c button2b.c 0 0 1 8 1 0 0 0 ..\main.c main.c 0 0 nucleo-h743zi 1 0 0 0 2 9 2 0 0 0 ..\..\..\..\3rd_party\nucleo-h743zi\arm\startup_stm32h743xx.s startup_stm32h743xx.s 0 0 2 10 5 0 0 0 ..\..\..\..\3rd_party\nucleo-h743zi\stm32h743xx.h stm32h743xx.h 0 0 2 11 1 0 0 0 ..\..\..\..\3rd_party\nucleo-h743zi\system_stm32h7xx.c system_stm32h7xx.c 0 0 sst 1 0 0 0 3 12 1 0 0 0 ..\..\..\src\sst0.c sst0.c 0 0 sst_port 1 0 0 0 4 13 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.h sst_port.h 0 0
================================================ FILE: sst0_c/examples/blinky_button/armclang/nucleo-h743zi.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
arm-nucleo-h743zi 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32H743ZITx STMicroelectronics Keil.STM32H7xx_DFP.3.0.0 http://www.keil.com/pack/ IRAM(0x20000000,0x00020000) IRAM2(0x24000000,0x00080000) IROM(0x08000000,0x00200000) CPUTYPE("Cortex-M7") FPU3(DFPU) CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32H7x_2048 -FS08000000 -FL0200000 -FP0($$Device:STM32H743ZITx$CMSIS\Flash\STM32H7x_2048.FLM)) 0 $$Device:STM32H743ZITx$Drivers\CMSIS\Device\ST\STM32H7xx\Include\stm32h7xx.h $$Device:STM32H743ZITx$CMSIS\SVD\STM32H7x3.svd 0 0 0 0 0 0 1 .\build_nucleo-h743zi\ blinky_button 1 0 0 1 1 .\build_nucleo-h743zi\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-h743zi\blinky_button.bin .\build_nucleo-h743zi\blinky_button.axf 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP -MPU DCM.DLL -pCM7 SARMCM3.DLL -MPU TCM.DLL -pCM7 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL "" () 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M7" 0 0 0 1 1 0 0 3 0 0 1 0 8 0 0 0 0 3 4 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x20000 1 0x8000000 0x200000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x200000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x20000 0 0x24000000 0x80000 0 1 0 0 1 0 0 0 0 0 3 0 1 0 0 0 3 3 0 0 0 0 0 STM32H743xx .;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-h743zi 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Applicatioin blinky_button.h 5 ..\blinky_button.h blinky1.c 1 ..\blinky1.c blinky3.c 1 ..\blinky3.c bsp.h 5 ..\bsp.h bsp_nucleo-h743zi.c 1 ..\bsp_nucleo-h743zi.c button2a.c 1 ..\button2a.c button2b.c 1 ..\button2b.c main.c 1 ..\main.c nucleo-h743zi startup_stm32h743xx.s 2 ..\..\..\..\3rd_party\nucleo-h743zi\arm\startup_stm32h743xx.s stm32h743xx.h 5 ..\..\..\..\3rd_party\nucleo-h743zi\stm32h743xx.h system_stm32h7xx.c 1 ..\..\..\..\3rd_party\nucleo-h743zi\system_stm32h7xx.c sst sst0.c 1 ..\..\..\src\sst0.c sst_port sst_port.h 5 ..\..\..\ports\arm-cm\sst_port.h nucleo-h743zi 1
================================================ FILE: sst0_c/examples/blinky_button/armclang/nucleo-l053r8.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 nucleo-l053r8 0x4 ARM-ADS 12000000 1 1 0 1 0 1 65535 0 0 0 79 66 8 .\build_nucleo-l053r8\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 UL2CM3 UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM)) 0 ST-LINKIII-KEIL_SWO -U066CFF484951775087074312 -O8431 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P2 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC800 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=1702,853,2113,1355,0)(1007=2082,245,2289,466,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS 0 0 188 1
0
0 0 0 0 0 0 ..\bsp_nucleo-l053r8.c
1 0 200 1
0
0 0 0 0 0 0 ..\bsp_nucleo-l053r8.c
1 2 0xE000E400 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 10000000
Application 1 0 0 0 1 1 5 0 0 0 ..\blinky_button.h blinky_button.h 0 0 1 2 1 0 0 0 ..\blinky1.c blinky1.c 0 0 1 3 1 0 0 0 ..\blinky3.c blinky3.c 0 0 1 4 5 0 0 0 ..\bsp.h bsp.h 0 0 1 5 1 0 0 0 ..\bsp_nucleo-l053r8.c bsp_nucleo-l053r8.c 0 0 1 6 1 0 0 0 ..\button2a.c button2a.c 0 0 1 7 1 0 0 0 ..\button2b.c button2b.c 0 0 1 8 1 0 0 0 ..\main.c main.c 0 0 nucleo-l053r8 1 0 0 0 2 9 2 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s startup_stm32l053xx.s 0 0 2 10 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l0xx.h 0 0 2 11 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h stm32l053xx.h 0 0 2 12 1 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c system_stm32l0xx.c 0 0 sst 1 0 0 0 3 13 1 0 0 0 ..\..\..\src\sst0.c sst0.c 0 0 sst_port 1 0 0 0 4 14 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.h sst_port.h 0 0
================================================ FILE: sst0_c/examples/blinky_button/armclang/nucleo-l053r8.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
nucleo-l053r8 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32L053R8Tx STMicroelectronics Keil.STM32L0xx_DFP.2.2.0 http://www.keil.com/pack/ IRAM(0x20000000,0x00002000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$Flash\STM32L0xx_64.FLM)) 0 $$Device:STM32L053R8Tx$Device\Include\stm32l0xx.h $$Device:STM32L053R8Tx$SVD\STM32L053x.svd 0 0 0 0 0 0 1 .\build_nucleo-l053r8\ blinky_button 1 0 0 1 1 .\build_nucleo-l053r8\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-l053r8\blinky_button.bin .\build_nucleo-l053r8\blinky_button.axf 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP DARMCM1.DLL -pCM0+ SARMCM3.DLL TARMCM1.DLL -pCM0+ 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M0+" 0 0 0 1 1 0 0 0 0 0 0 0 8 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 1 0x8000000 0x10000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x10000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 0 0x0 0x0 0 0 0 0 1 0 0 0 0 0 4 0 1 0 0 0 3 3 0 0 0 0 0 -Wno-padded .;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-l053r8 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Application blinky_button.h 5 ..\blinky_button.h blinky1.c 1 ..\blinky1.c blinky3.c 1 ..\blinky3.c bsp.h 5 ..\bsp.h bsp_nucleo-l053r8.c 1 ..\bsp_nucleo-l053r8.c button2a.c 1 ..\button2a.c button2b.c 1 ..\button2b.c main.c 1 ..\main.c nucleo-l053r8 startup_stm32l053xx.s 2 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s stm32l0xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l053xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h system_stm32l0xx.c 1 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c sst sst0.c 1 ..\..\..\src\sst0.c sst_port sst_port.h 5 ..\..\..\ports\arm-cm\sst_port.h nucleo-l053r8 1
================================================ FILE: sst0_c/examples/blinky_button/blinky1.c ================================================ /*============================================================================ * Super-Simple Tasker (SST0/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky_button.h" /* application shared interface */ DBC_MODULE_NAME("blinky1") /* for DBC assertions in this module */ /*..........................................................................*/ typedef struct { /* Blinky1 task */ SST_Task super; /* inherit SST_Task */ SST_TimeEvt te; /* time event for generating TIMEOUT events */ uint16_t toggles; /* number of toggles to perform for TIMEOUT event */ } Blinky1; static void Blinky1_ctor(Blinky1 * const me); static void Blinky1_init(Blinky1 * const me, SST_Evt const * const ie); static void Blinky1_dispatch(Blinky1 * const me, SST_Evt const * const e); /*..........................................................................*/ static Blinky1 Blinky1_inst; /* the Blinky instance */ SST_Task * const AO_Blinky1 = &Blinky1_inst.super; /* opaque AO pointer */ void Blinky1_instantiate(void) { Blinky1_ctor(&Blinky1_inst); } /*..........................................................................*/ static void Blinky1_ctor(Blinky1 * const me) { SST_Task_ctor( &me->super, (SST_Handler)&Blinky1_init, (SST_Handler)&Blinky1_dispatch); SST_TimeEvt_ctor(&me->te, TIMEOUT_SIG, &me->super); } /*..........................................................................*/ static void Blinky1_init(Blinky1 * const me, SST_Evt const * const ie) { /* the initial event must be provided and must be WORKLOAD_SIG */ DBC_REQUIRE(300, (ie != (SST_Evt const *)0) && (ie->sig == BLINKY_WORK_SIG)); SST_TimeEvt_arm(&me->te, SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks, SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks); me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->toggles; } /*..........................................................................*/ static void Blinky1_dispatch(Blinky1 * const me, SST_Evt const * const e) { switch (e->sig) { case TIMEOUT_SIG: { for (uint16_t i = me->toggles; i > 0U; --i) { /* SST scheduler lock is not needed in non-preemptive SST0 */ //SST_LockKey key = SST_Task_lock(3U); BSP_d5on(); BSP_d5off(); //SST_Task_unlock(key); } break; } case BLINKY_WORK_SIG: { BSP_d5on(); SST_TimeEvt_arm(&me->te, SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks, SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks); me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->toggles; BSP_d5off(); break; } default: { DBC_ERROR(500); /* unexpected event */ break; } } } ================================================ FILE: sst0_c/examples/blinky_button/blinky3.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky_button.h" /* application shared interface */ DBC_MODULE_NAME("blinky3") /* for DBC assertions in this module */ /*..........................................................................*/ typedef struct { /* Blinky3 task */ SST_Task super; /* inherit SST_Task */ SST_TimeEvt te; /* time event for generating TIMEOUT events */ uint16_t toggles; /* number of toggles to perform for TIMEOUT event */ } Blinky3; static void Blinky3_ctor(Blinky3 * const me); static void Blinky3_init(Blinky3 * const me, SST_Evt const * const ie); static void Blinky3_dispatch(Blinky3 * const me, SST_Evt const * const e); /*..........................................................................*/ static Blinky3 Blinky3_inst; /* the Blinky3 instance */ SST_Task * const AO_Blinky3 = &Blinky3_inst.super; /* opaque AO pointer */ void Blinky3_instantiate(void) { Blinky3_ctor(&Blinky3_inst); } /*..........................................................................*/ static void Blinky3_ctor(Blinky3 * const me) { SST_Task_ctor( &me->super, (SST_Handler)&Blinky3_init, (SST_Handler)&Blinky3_dispatch); SST_TimeEvt_ctor(&me->te, TIMEOUT_SIG, &me->super); } /*..........................................................................*/ static void Blinky3_init(Blinky3 * const me, SST_Evt const * const ie) { /* the initial event must be provided and must be WORKLOAD_SIG */ DBC_REQUIRE(300, (ie != (SST_Evt const *)0) && (ie->sig == BLINKY_WORK_SIG)); SST_TimeEvt_arm(&me->te, SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks, SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks); me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->toggles; } /*..........................................................................*/ static void Blinky3_dispatch(Blinky3 * const me, SST_Evt const * const e) { switch (e->sig) { case TIMEOUT_SIG: { for (uint16_t i = me->toggles; i > 0U; --i) { BSP_d2on(); BSP_d2off(); } break; } case BLINKY_WORK_SIG: { BSP_d2on(); SST_TimeEvt_arm(&me->te, SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks, SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks); me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->toggles; BSP_d2off(); break; } default: { DBC_ERROR(500); /* unexpected event */ break; } } } ================================================ FILE: sst0_c/examples/blinky_button/blinky_button.h ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #ifndef BLINKY_BUTTON_H_ #define BLINKY_BUTTON_H_ #include "dbc_assert.h" /* Design By Contract (DBC) assertions */ enum Signals { TIMEOUT_SIG, BUTTON_PRESSED_SIG, BUTTON_RELEASED_SIG, BLINKY_WORK_SIG, FORWARD_PRESSED_SIG, FORWARD_RELEASED_SIG, /* ... */ MAX_SIG /* the last signal */ }; typedef struct { SST_Evt super; /* inherit SST_Evt */ uint16_t toggles; /* number of toggles of the signal */ uint8_t ticks; /* number of clock ticks between */ } BlinkyWorkEvt; typedef struct { SST_Evt super; /* inherit SST_Evt */ uint16_t toggles; /* number of toggles of the signal */ } ButtonWorkEvt; void Blinky1_instantiate(void); extern SST_Task * const AO_Blinky1; /* opaque task pointer */ void Blinky3_instantiate(void); extern SST_Task * const AO_Blinky3; /* opaque task pointer */ void Button2a_instantiate(void); extern SST_Task * const AO_Button2a; /* opaque task pointer */ void Button2b_instantiate(void); extern SST_Task * const AO_Button2b; /* opaque task pointer */ #endif /* BLINKY_BUTTON_H_ */ ================================================ FILE: sst0_c/examples/blinky_button/bsp.h ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #ifndef BSP_H_ #define BSP_H_ #define BSP_TICKS_PER_SEC 1000U void BSP_init(void); void BSP_d1on(void); void BSP_d1off(void); void BSP_d2on(void); void BSP_d2off(void); void BSP_d3on(void); void BSP_d3off(void); void BSP_d4on(void); void BSP_d4off(void); void BSP_d5on(void); void BSP_d5off(void); void BSP_d6on(void); void BSP_d6off(void); /* immutable events for Blinky tasks */ SST_Evt const *BSP_getWorkEvtBlinky1(uint8_t num); SST_Evt const *BSP_getWorkEvtBlinky3(uint8_t num); #endif /* BSP_H_ */ ================================================ FILE: sst0_c/examples/blinky_button/bsp_ek-tm4c123gxl.c ================================================ /*============================================================================ * Super-Simple Tasker (SST0/C) Example for TivaC TM4C123GXL * * Q u a n t u m L e a P s * ------------------------ * Modern Embedded Software * * Copyright (C) 2005 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" #include "bsp.h" #include "blinky_button.h" #include "TM4C123GH6PM.h" /* the device specific header (TI) */ #include /* to exercise the FPU */ /* add other drivers if necessary... */ DBC_MODULE_NAME("bsp_ek-tm4c123gxl") /* for DBC assertions in this module */ /* Local-scope defines -----------------------------------------------------*/ /* test pins on GPIOF */ #define TST1_PIN (1U << 1U) /* LED Red */ #define TST2_PIN (1U << 2U) /* LED Blue */ /* test pins on GPIOD */ #define TST3_PIN (1U << 0U) #define TST4_PIN (1U << 1U) #define TST5_PIN (1U << 2U) /* test pins on GPIOF */ #define TST6_PIN (1U << 3U) /* LED Green */ /* Button on the board on GPIOF */ #define BTN_SW1 (1U << 4) /* ISRs used in the application ============================================*/ void SysTick_Handler(void); /* prototype */ void SysTick_Handler(void) { /* system clock tick ISR */ BSP_d1on(); SST_TimeEvt_tick(); /* process all SST time events */ /* Perform the debouncing of buttons. The algorithm for debouncing * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle * and Michael Barr, page 71. */ static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = ~GPIOF_AHB->DATA_Bits[BTN_SW1]; uint32_t tmp = buttons.depressed; /* save the debounced depressed */ buttons.depressed |= (buttons.previous & current); /* set depressed */ buttons.depressed &= (buttons.previous | current); /* clear released */ buttons.previous = current; /* update the history */ tmp ^= buttons.depressed; /* changed debounced depressed */ if ((tmp & BTN_SW1) != 0U) { /* debounced SW1 state changed? */ if ((buttons.depressed & BTN_SW1) != 0U) { /* is SW1 depressed? */ /* immutable button-press event */ static ButtonWorkEvt const pressEvt = { .super.sig = BUTTON_PRESSED_SIG, .toggles = 60U }; /* immutable forward-press event */ static ButtonWorkEvt const fPressEvt = { .super.sig = FORWARD_PRESSED_SIG, .toggles = 60U }; SST_Task_post(AO_Button2a, &fPressEvt.super); SST_Task_post(AO_Button2a, &pressEvt.super); } else { /* B1 is released */ /* immutable button-release event */ static ButtonWorkEvt const releaseEvt = { .super.sig = BUTTON_RELEASED_SIG, .toggles = 80U }; /* immutable forward-release event */ static ButtonWorkEvt const fReleaseEvt = { .super.sig = FORWARD_RELEASED_SIG, .toggles = 80U }; SST_Task_post(AO_Button2a, &fReleaseEvt.super); SST_Task_post(AO_Button2a, &releaseEvt.super); } } BSP_d1off(); } /* Assertion handler ======================================================*/ DBC_NORETURN void DBC_fault_handler(char const * const module, int const label) { /* * NOTE: add here your application-specific error handling */ (void)module; (void)label; /* set PRIMASK to disable interrupts and stop SST right here */ __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { /* keep blinking LED2 */ BSP_d6on(); /* turn LED2 on */ uint32_t volatile ctr; for (ctr = 1000000U; ctr > 0U; --ctr) { } BSP_d6off(); /* turn LED2 off */ for (ctr = 1000000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } /*..........................................................................*/ void assert_failed(char const * const module, int const label);/* prototype */ void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } /* BSP functions ===========================================================*/ void BSP_init(void) { /* Configure the MPU to prevent NULL-pointer dereferencing * see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu */ MPU->RBAR = 0x0U /* base address (NULL) */ | MPU_RBAR_VALID_Msk /* valid region */ | (MPU_RBAR_REGION_Msk & 7U); /* region #7 */ MPU->RASR = (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1) region */ | (0x0U << MPU_RASR_AP_Pos) /* no-access region */ | MPU_RASR_ENABLE_Msk; /* region enable */ MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk /* enable background region */ | MPU_CTRL_ENABLE_Msk; /* enable the MPU */ __ISB(); __DSB(); SYSCTL->RCGCGPIO |= (1U << 5U); /* enable Run mode for GPIOF */ SYSCTL->RCGCGPIO |= (1U << 3U); /* enable Run mode for GPIOD */ __ISB(); __DSB(); SYSCTL->GPIOHBCTL |= (1U << 5); /* enable AHB for GPIOF */ SYSCTL->GPIOHBCTL |= (1U << 3); /* enable AHB for GPIOD */ __ISB(); __DSB(); /* configure test pins on GPIOF (digital output) */ GPIOF_AHB->DIR |= (TST1_PIN | TST2_PIN | TST6_PIN); GPIOF_AHB->DEN |= (TST1_PIN | TST2_PIN | TST6_PIN); /* configure button on GPIOF (digital input) */ GPIOF_AHB->DIR &= ~(BTN_SW1); /* input */ GPIOF_AHB->DEN |= (BTN_SW1); /* digital enable */ GPIOF_AHB->PUR |= (BTN_SW1); /* pull-up resistor enable */ /* configure test pins on GPIOD (digital output) */ GPIOD_AHB->DIR |= (TST3_PIN | TST4_PIN | TST5_PIN); GPIOD_AHB->DEN |= (TST3_PIN | TST4_PIN | TST5_PIN); } /*..........................................................................*/ #if defined __ARMCC_VERSION #elif defined __GNUC__ uint32_t __errno; /* GNU-ARM needs this to link sqrtf() */ #endif static void exerciseFPU(float x) { /* exercise the single-precision FPU by calculating the identity: * sqrt(x) == x / sqrt(x) for x > 0 */ float tmp1 = sqrtf(x); /* single-precision sqrt() */ float tmp2 = x / tmp1; DBC_ENSURE(200, (tmp1 - 1e-4f <= tmp2) && (tmp2 <= tmp1 + 1e-4f)); } /*..........................................................................*/ void BSP_d1on(void) { /* LED-Red */ GPIOF_AHB->DATA_Bits[TST1_PIN] = 0xFFU; /* don't use the FPU in the ISR */ } void BSP_d1off(void) { GPIOF_AHB->DATA_Bits[TST1_PIN] = 0x00U; } /*..........................................................................*/ void BSP_d2on(void) { /* LED-Blue */ GPIOF_AHB->DATA_Bits[TST2_PIN] = 0xFFU; exerciseFPU(1.2345f); } void BSP_d2off(void) { GPIOF_AHB->DATA_Bits[TST2_PIN] = 0x00U; } /*..........................................................................*/ void BSP_d3on(void) { GPIOD_AHB->DATA_Bits[TST3_PIN] = 0xFFU; exerciseFPU(0.345f); } void BSP_d3off(void) { GPIOD_AHB->DATA_Bits[TST3_PIN] = 0x00U; } /*..........................................................................*/ void BSP_d4on(void) { GPIOD_AHB->DATA_Bits[TST4_PIN] = 0xFFU; exerciseFPU(0.456f); } void BSP_d4off(void) { GPIOD_AHB->DATA_Bits[TST4_PIN] = 0x00U; } /*..........................................................................*/ void BSP_d5on(void) { GPIOD_AHB->DATA_Bits[TST5_PIN] = 0xFFU; exerciseFPU(1.567f); } void BSP_d5off(void) { GPIOD_AHB->DATA_Bits[TST5_PIN] = 0x00U; } /*..........................................................................*/ void BSP_d6on(void) { /* LED2-Green */ GPIOF_AHB->DATA_Bits[TST6_PIN] = 0xFFU; exerciseFPU(1.2345f); } void BSP_d6off(void) { GPIOF_AHB->DATA_Bits[TST6_PIN] = 0x00U; } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky1(uint8_t num) { /* immutable work events for Blinky1 */ static BlinkyWorkEvt const workBlinky1[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 40U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 30U, .ticks = 7U, } }; DBC_REQUIRE(500, num < ARRAY_NELEM(workBlinky1)); /* must be in range */ return &workBlinky1[num].super; } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky3(uint8_t num) { /* immutable work events for Blinky3 */ static BlinkyWorkEvt const workBlinky3[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 20U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 10U, .ticks = 3U, } }; DBC_REQUIRE(600, num < ARRAY_NELEM(workBlinky3)); /* must be in range */ return &workBlinky3[num].super; } /* SST callbacks ===========================================================*/ void SST_onStart(void) { SystemCoreClockUpdate(); /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ SysTick_Config((SystemCoreClock / BSP_TICKS_PER_SEC) + 1U); /* set priorities of ISRs used in the system */ NVIC_SetPriority(SysTick_IRQn, 0U); /* ... */ } /*..........................................................................*/ void SST_onIdleCond(void) { /* NOTE: called with interrupts DISABLED */ BSP_d6on(); /* turn LED-Green on */ #ifdef NDEBUG /* Put the CPU and peripherals to the low-power mode. * you might need to customize the clock management for your application, * see the datasheet for your particular Cortex-M MCU. */ BSP_d6off(); /* turn LED-Green off */ __WFI(); /* Wait-For-Interrupt */ BSP_d6on(); /* turn LED-Green on */ #endif BSP_d6off(); /* turn LED-Green off */ SST_PORT_INT_ENABLE(); /* NOTE: enable interrupts for SS0 */ } ================================================ FILE: sst0_c/examples/blinky_button/bsp_nucleo-c031c6.c ================================================ /*============================================================================ * Super-Simple Tasker (SST0/C) Example for STM32 NUCLEO-C031C6 * * Q u a n t u m L e a P s * ------------------------ * Modern Embedded Software * * Copyright (C) 2005 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" #include "bsp.h" #include "blinky_button.h" #include "stm32c0xx.h" /* CMSIS-compliant header file for the MCU used */ /* add other drivers if necessary... */ DBC_MODULE_NAME("bsp_nucleo-c031c6") /* Local-scope defines -----------------------------------------------------*/ /* test pins on GPIO PA */ #define TST1_PIN 7U #define TST2_PIN 6U #define TST3_PIN 4U #define TST4_PIN 1U #define TST5_PIN 0U #define TST6_PIN 5U /* LED L4-Green */ /* buttons on GPIO PC */ #define B1_PIN 13U /* ISRs used in the application ============================================*/ void SysTick_Handler(void); /* prototype */ void SysTick_Handler(void) { /* system clock tick ISR */ BSP_d1on(); SST_TimeEvt_tick(); /* process all SST time events */ /* Perform the debouncing of buttons. The algorithm for debouncing * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle * and Michael Barr, page 71. */ static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = ~GPIOC->IDR; /* read GPIO PortC */ uint32_t tmp = buttons.depressed; /* save the debounced depressed */ buttons.depressed |= (buttons.previous & current); /* set depressed */ buttons.depressed &= (buttons.previous | current); /* clear released */ buttons.previous = current; /* update the history */ tmp ^= buttons.depressed; /* changed debounced depressed */ if ((tmp & (1U << B1_PIN)) != 0U) { /* debounced B1 state changed? */ if ((buttons.depressed & (1U << B1_PIN)) != 0U) { /* depressed? */ /* immutable button-press event */ static ButtonWorkEvt const pressEvt = { .super.sig = BUTTON_PRESSED_SIG, .toggles = 60U }; /* immutable forward-press event */ static ButtonWorkEvt const fPressEvt = { .super.sig = FORWARD_PRESSED_SIG, .toggles = 60U }; SST_Task_post(AO_Button2a, &fPressEvt.super); SST_Task_post(AO_Button2a, &pressEvt.super); } else { /* B1 is released */ /* immutable button-release event */ static ButtonWorkEvt const releaseEvt = { .super.sig = BUTTON_RELEASED_SIG, .toggles = 80U }; /* immutable forward-release event */ static ButtonWorkEvt const fReleaseEvt = { .super.sig = FORWARD_RELEASED_SIG, .toggles = 80U }; SST_Task_post(AO_Button2a, &fReleaseEvt.super); SST_Task_post(AO_Button2a, &releaseEvt.super); } } BSP_d1off(); } /* Assertion handler ======================================================*/ DBC_NORETURN void DBC_fault_handler(char const * const module, int const label) { /* * NOTE: add here your application-specific error handling */ (void)module; (void)label; /* set PRIMASK to disable interrupts and stop SST right here */ __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { /* keep blinking LED2 */ BSP_d6on(); /* turn LD4 on */ uint32_t volatile ctr; for (ctr = 100000U; ctr > 0U; --ctr) { } BSP_d6off(); /* turn LD4 off */ for (ctr = 100000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } /*..........................................................................*/ void assert_failed(char const * const module, int const label);/* prototype */ void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } /* BSP functions ===========================================================*/ void BSP_init(void) { /* Configure the MPU to prevent NULL-pointer dereferencing * see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu */ MPU->RBAR = 0x0U /* base address (NULL) */ | MPU_RBAR_VALID_Msk /* valid region */ | (MPU_RBAR_REGION_Msk & 7U); /* region #7 */ MPU->RASR = (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1) region */ | (0x0U << MPU_RASR_AP_Pos) /* no-access region */ | MPU_RASR_ENABLE_Msk; /* region enable */ MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk /* enable background region */ | MPU_CTRL_ENABLE_Msk; /* enable the MPU */ __ISB(); __DSB(); /* enable GPIO port PA clock */ RCC->IOPENR |= (1U << 0U); /* set all used GPIOA pins as push-pull output, no pull-up, pull-down */ GPIOA->MODER &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); GPIOA->MODER |= ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); GPIOA->OTYPER &= ~((1U << TST1_PIN) | (1U << TST2_PIN) | (1U << TST3_PIN) | (1U << TST4_PIN) | (1U << TST5_PIN) | (1U << TST6_PIN)); GPIOA->OSPEEDR &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); GPIOA->OSPEEDR |= ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); GPIOA->PUPDR &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); /* enable GPIOC clock port for the Button B1 */ RCC->IOPENR |= (1U << 2U); /* configure Button B1 pin on GPIOC as input, no pull-up, pull-down */ GPIOC->MODER &= ~(3U << 2U*B1_PIN); GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); } /*..........................................................................*/ void BSP_d1on(void) { GPIOA->BSRR = (1U << TST1_PIN); } void BSP_d1off(void) { GPIOA->BSRR = (1U << (TST1_PIN + 16U)); } /*..........................................................................*/ void BSP_d2on(void) { GPIOA->BSRR = (1U << TST2_PIN); } void BSP_d2off(void) { GPIOA->BSRR = (1U << (TST2_PIN + 16U)); } /*..........................................................................*/ void BSP_d3on(void) { GPIOA->BSRR = (1U << TST3_PIN); } void BSP_d3off(void) { GPIOA->BSRR = (1U << (TST3_PIN + 16U)); } /*..........................................................................*/ void BSP_d4on(void) { GPIOA->BSRR = (1U << TST4_PIN); } void BSP_d4off(void) { GPIOA->BSRR = (1U << (TST4_PIN + 16U)); } /*..........................................................................*/ void BSP_d5on(void) { GPIOA->BSRR = (1U << TST5_PIN); } void BSP_d5off(void) { GPIOA->BSRR = (1U << (TST5_PIN + 16U)); } /*..........................................................................*/ void BSP_d6on(void) { GPIOA->BSRR = (1U << TST6_PIN); } /* LD4 */ void BSP_d6off(void) { GPIOA->BSRR = (1U << (TST6_PIN + 16U)); } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky1(uint8_t num) { /* immutable work events for Blinky1 */ static BlinkyWorkEvt const workBlinky1[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 40U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 30U, .ticks = 7U, } }; DBC_REQUIRE(500, num < ARRAY_NELEM(workBlinky1)); /* must be in range */ return &workBlinky1[num].super; } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky3(uint8_t num) { /* immutable work events for Blinky3 */ static BlinkyWorkEvt const workBlinky3[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 20U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 10U, .ticks = 3U, } }; DBC_REQUIRE(600, num < ARRAY_NELEM(workBlinky3)); /* must be in range */ return &workBlinky3[num].super; } /* SST callbacks ===========================================================*/ void SST_onStart(void) { SystemCoreClockUpdate(); /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ SysTick_Config((SystemCoreClock / BSP_TICKS_PER_SEC) + 1U); /* set priorities of ISRs used in the system */ NVIC_SetPriority(SysTick_IRQn, 0U); /* ... */ } /*..........................................................................*/ void SST_onIdleCond(void) { /* NOTE: called with interrupts DISABLED */ BSP_d6on(); /* turn LED2 on */ #ifdef NDEBUG /* Put the CPU and peripherals to the low-power mode. * you might need to customize the clock management for your application, * see the datasheet for your particular Cortex-M MCU. */ BSP_d6off(); /* turn LED2 off */ __WFI(); /* Wait-For-Interrupt */ BSP_d6on(); /* turn LED2 on */ #endif BSP_d6off(); /* turn LED2 off */ SST_PORT_INT_ENABLE(); /* NOTE: enable interrupts for SS0 */ } ================================================ FILE: sst0_c/examples/blinky_button/bsp_nucleo-h743zi.c ================================================ /*============================================================================ * Super-Simple Tasker (SST0/C) Example for STM32 NUCLEO-H743ZI * * Q u a n t u m L e a P s * ------------------------ * Modern Embedded Software * * Copyright (C) 2005 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" #include "bsp.h" #include "blinky_button.h" #include "stm32h743xx.h" /* CMSIS-compliant header file for the MCU used */ #include /* to exercise the FPU */ /* add other drivers if necessary... */ DBC_MODULE_NAME("bsp_nucleo-h743zi") /* for DBC assertions in this module */ /* Local-scope defines -----------------------------------------------------*/ /* test pins on GPIO PB */ #define TST1_PIN 0U /* PB.0 LED1-Green */ #define TST2_PIN 14U /* PB.14 LED3-Red */ #define TST3_PIN 4U #define TST4_PIN 5U #define TST5_PIN 6U #define TST6_PIN 7U /* PB.7 LED2-Blue */ /* buttons on GPIO PC */ #define B1_PIN 13U /* ISRs used in the application ============================================*/ void SysTick_Handler(void); /* prototype */ void SysTick_Handler(void) { /* system clock tick ISR */ BSP_d1on(); SST_TimeEvt_tick(); /* process all SST time events */ /* Perform the debouncing of buttons. The algorithm for debouncing * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle * and Michael Barr, page 71. */ static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = GPIOC->IDR; /* read GPIO PortC */ uint32_t tmp = buttons.depressed; /* save the debounced depressed */ buttons.depressed |= (buttons.previous & current); /* set depressed */ buttons.depressed &= (buttons.previous | current); /* clear released */ buttons.previous = current; /* update the history */ tmp ^= buttons.depressed; /* changed debounced depressed */ if ((tmp & (1U << B1_PIN)) != 0U) { /* debounced B1 state changed? */ if ((buttons.depressed & (1U << B1_PIN)) != 0U) { /* depressed? */ /* immutable button-press event */ static ButtonWorkEvt const pressEvt = { .super.sig = BUTTON_PRESSED_SIG, .toggles = 60U }; /* immutable forward-press event */ static ButtonWorkEvt const fPressEvt = { .super.sig = FORWARD_PRESSED_SIG, .toggles = 60U }; SST_Task_post(AO_Button2a, &fPressEvt.super); SST_Task_post(AO_Button2a, &pressEvt.super); } else { /* B1 is released */ /* immutable button-release event */ static ButtonWorkEvt const releaseEvt = { .super.sig = BUTTON_RELEASED_SIG, .toggles = 80U }; /* immutable forward-release event */ static ButtonWorkEvt const fReleaseEvt = { .super.sig = FORWARD_RELEASED_SIG, .toggles = 80U }; SST_Task_post(AO_Button2a, &fReleaseEvt.super); SST_Task_post(AO_Button2a, &releaseEvt.super); } } BSP_d1off(); } /* Assertion handler ======================================================*/ DBC_NORETURN void DBC_fault_handler(char const * const module, int const label) { /* * NOTE: add here your application-specific error handling */ (void)module; (void)label; /* set PRIMASK to disable interrupts and stop SST right here */ __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { /* keep blinking LED2 */ BSP_d6on(); /* turn LED2 on */ uint32_t volatile ctr; for (ctr = 1000000U; ctr > 0U; --ctr) { } BSP_d6off(); /* turn LED2 off */ for (ctr = 1000000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } /*..........................................................................*/ void assert_failed(char const * const module, int const label);/* prototype */ void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } /* BSP functions ===========================================================*/ void BSP_init(void) { /* Configure the MPU to prevent NULL-pointer dereferencing * see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu */ MPU->RBAR = 0x0U /* base address (NULL) */ | MPU_RBAR_VALID_Msk /* valid region */ | (MPU_RBAR_REGION_Msk & 7U); /* region #7 */ MPU->RASR = (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1) region */ | (0x0U << MPU_RASR_AP_Pos) /* no-access region */ | MPU_RASR_ENABLE_Msk; /* region enable */ MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk /* enable background region */ | MPU_CTRL_ENABLE_Msk; /* enable the MPU */ __ISB(); __DSB(); SCB_EnableICache(); /* Enable I-Cache */ SCB_EnableDCache(); /* Enable D-Cache */ /* enable GPIOB port clock for LEds and test pins */ RCC->AHB4ENR |= RCC_AHB4ENR_GPIOBEN; /* set all used GPIOB pins as push-pull output, no pull-up, pull-down */ GPIOB->MODER &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); GPIOB->MODER |= ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); GPIOB->OTYPER &= ~((1U << TST1_PIN) | (1U << TST2_PIN) | (1U << TST3_PIN) | (1U << TST4_PIN) | (1U << TST5_PIN) | (1U << TST6_PIN)); GPIOB->PUPDR &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); /* enable GPIOC clock port for the Button B1 */ RCC->AHB4ENR |= RCC_AHB4ENR_GPIOCEN; /* configure Button B1 pin on GPIOC as input, no pull-up, pull-down */ GPIOC->MODER &= ~(3U << 2U*B1_PIN); GPIOC->PUPDR &= ~(GPIO_PUPDR_PUPD0 << 2U*B1_PIN); GPIOC->PUPDR |= (2U << 2U*B1_PIN); } /*..........................................................................*/ static void exerciseFPU(double x) { /* exercise the double-precision FPU by calculating the identity: * sin(x)^2 + cos(x)^2 == 1.0 for any x */ double tmp = pow(sin(x), 2.0) + pow(cos(x), 2.0); DBC_ENSURE(200, (1.0 - 1e-4 < tmp) && (tmp < 1.0 + 1e-4)); } /*..........................................................................*/ void BSP_d1on(void) { /* LED1-Green */ GPIOB->BSRR = (1U << TST1_PIN); /* don't use the FPU in the ISR */ } void BSP_d1off(void) { GPIOB->BSRR = (1U << (TST1_PIN + 16U)); } /*..........................................................................*/ void BSP_d2on(void) { /* LED3-Red */ GPIOB->BSRR = (1U << TST2_PIN); exerciseFPU(-1.2345); } void BSP_d2off(void) { GPIOB->BSRR = (1U << (TST2_PIN + 16U)); } /*..........................................................................*/ void BSP_d3on(void) { GPIOB->BSRR = (1U << TST3_PIN); exerciseFPU(-12.345); } void BSP_d3off(void) { GPIOB->BSRR = (1U << (TST3_PIN + 16U)); } /*..........................................................................*/ void BSP_d4on(void) { GPIOB->BSRR = (1U << TST4_PIN); exerciseFPU(3.456); } void BSP_d4off(void) { GPIOB->BSRR = (1U << (TST4_PIN + 16U)); } /*..........................................................................*/ void BSP_d5on(void) { GPIOB->BSRR = (1U << TST5_PIN); exerciseFPU(4.567); } void BSP_d5off(void) { GPIOB->BSRR = (1U << (TST5_PIN + 16U)); } /*..........................................................................*/ void BSP_d6on(void) { /* LED2-Blue */ GPIOB->BSRR = (1U << TST6_PIN); exerciseFPU(1.2345); } void BSP_d6off(void) { GPIOB->BSRR = (1U << (TST6_PIN + 16U)); } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky1(uint8_t num) { /* immutable work events for Blinky1 */ static BlinkyWorkEvt const workBlinky1[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 40U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 30U, .ticks = 7U, } }; DBC_REQUIRE(500, num < ARRAY_NELEM(workBlinky1)); /* must be in range */ return &workBlinky1[num].super; } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky3(uint8_t num) { /* immutable work events for Blinky3 */ static BlinkyWorkEvt const workBlinky3[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 20U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 10U, .ticks = 3U, } }; DBC_REQUIRE(600, num < ARRAY_NELEM(workBlinky3)); /* must be in range */ return &workBlinky3[num].super; } /* SST callbacks ===========================================================*/ void SST_onStart(void) { SystemCoreClockUpdate(); /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ SysTick_Config((SystemCoreClock / BSP_TICKS_PER_SEC) + 1U); /* set priorities of ISRs used in the system */ NVIC_SetPriority(SysTick_IRQn, 0U); /* ... */ } /*..........................................................................*/ void SST_onIdleCond(void) { /* NOTE: called with interrupts DISABLED */ BSP_d6on(); /* turn LED2 on */ #ifdef NDEBUG /* Put the CPU and peripherals to the low-power mode. * you might need to customize the clock management for your application, * see the datasheet for your particular Cortex-M MCU. */ BSP_d6off(); /* turn LED2 off */ __WFI(); /* Wait-For-Interrupt */ BSP_d6on(); /* turn LED2 on */ #endif BSP_d6off(); /* turn LED2 off */ SST_PORT_INT_ENABLE(); /* NOTE: enable interrupts for SS0 */ } ================================================ FILE: sst0_c/examples/blinky_button/bsp_nucleo-l053r8.c ================================================ /*============================================================================ * Super-Simple Tasker (SST0/C) Example for STM32 NUCLEO-L053R8 * * Q u a n t u m L e a P s * ------------------------ * Modern Embedded Software * * Copyright (C) 2005 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" #include "bsp.h" #include "blinky_button.h" #include "stm32l0xx.h" /* CMSIS-compliant header file for the MCU used */ /* add other drivers if necessary... */ DBC_MODULE_NAME("bsp_nucleo-l053r8") /* for DBC assertions in this module */ /* Local-scope defines -----------------------------------------------------*/ /* test pins on GPIO PA */ #define TST1_PIN 7U #define TST2_PIN 6U #define TST3_PIN 4U #define TST4_PIN 1U #define TST5_PIN 0U #define TST6_PIN 5U /* LED LD2-Green */ /* buttons on GPIO PC */ #define B1_PIN 13U /* ISRs used in the application ============================================*/ void SysTick_Handler(void); /* prototype */ void SysTick_Handler(void) { /* system clock tick ISR */ BSP_d1on(); SST_TimeEvt_tick(); /* process all SST time events */ /* Perform the debouncing of buttons. The algorithm for debouncing * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle * and Michael Barr, page 71. */ static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = ~GPIOC->IDR; /* read GPIO PortC */ uint32_t tmp = buttons.depressed; /* save the debounced depressed */ buttons.depressed |= (buttons.previous & current); /* set depressed */ buttons.depressed &= (buttons.previous | current); /* clear released */ buttons.previous = current; /* update the history */ tmp ^= buttons.depressed; /* changed debounced depressed */ if ((tmp & (1U << B1_PIN)) != 0U) { /* debounced B1 state changed? */ if ((buttons.depressed & (1U << B1_PIN)) != 0U) { /* depressed? */ /* immutable button-press event */ static ButtonWorkEvt const pressEvt = { .super.sig = BUTTON_PRESSED_SIG, .toggles = 60U }; /* immutable forward-press event */ static ButtonWorkEvt const fPressEvt = { .super.sig = FORWARD_PRESSED_SIG, .toggles = 60U }; SST_Task_post(AO_Button2a, &fPressEvt.super); SST_Task_post(AO_Button2a, &pressEvt.super); } else { /* B1 is released */ /* immutable button-release event */ static ButtonWorkEvt const releaseEvt = { .super.sig = BUTTON_RELEASED_SIG, .toggles = 80U }; /* immutable forward-release event */ static ButtonWorkEvt const fReleaseEvt = { .super.sig = FORWARD_RELEASED_SIG, .toggles = 80U }; SST_Task_post(AO_Button2a, &fReleaseEvt.super); SST_Task_post(AO_Button2a, &releaseEvt.super); } } BSP_d1off(); } /* Assertion handler ======================================================*/ DBC_NORETURN void DBC_fault_handler(char const * const module, int const label) { /* * NOTE: add here your application-specific error handling */ (void)module; (void)label; /* set PRIMASK to disable interrupts and stop SST right here */ __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { /* keep blinking LED2 */ BSP_d6on(); /* turn LED2 on */ uint32_t volatile ctr; for (ctr = 10000U; ctr > 0U; --ctr) { } BSP_d6off(); /* turn LED2 off */ for (ctr = 10000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } /*..........................................................................*/ void assert_failed(char const * const module, int const label);/* prototype */ void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } /* BSP functions ===========================================================*/ void BSP_init(void) { /* Configure the MPU to prevent NULL-pointer dereferencing * see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu */ MPU->RBAR = 0x0U /* base address (NULL) */ | MPU_RBAR_VALID_Msk /* valid region */ | (MPU_RBAR_REGION_Msk & 7U); /* region #7 */ MPU->RASR = (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1) region */ | (0x0U << MPU_RASR_AP_Pos) /* no-access region */ | MPU_RASR_ENABLE_Msk; /* region enable */ MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk /* enable background region */ | MPU_CTRL_ENABLE_Msk; /* enable the MPU */ __ISB(); __DSB(); /* enable GPIO port PA clock */ RCC->IOPENR |= (1U << 0U); /* set all used GPIOA pins as push-pull output, no pull-up, pull-down */ GPIOA->MODER &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); GPIOA->MODER |= ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); GPIOA->OTYPER &= ~((1U << TST1_PIN) | (1U << TST2_PIN) | (1U << TST3_PIN) | (1U << TST4_PIN) | (1U << TST5_PIN) | (1U << TST6_PIN)); GPIOA->PUPDR &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); /* enable GPIOC clock port for the Button B1 */ RCC->IOPENR |= (1U << 2U); /* configure Button B1 pin on GPIOC as input, no pull-up, pull-down */ GPIOC->MODER &= ~(3U << 2U*B1_PIN); GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); } /*..........................................................................*/ void BSP_d1on(void) { GPIOA->BSRR = (1U << TST1_PIN); } void BSP_d1off(void) { GPIOA->BSRR = (1U << (TST1_PIN + 16U)); } /*..........................................................................*/ void BSP_d2on(void) { GPIOA->BSRR = (1U << TST2_PIN); } void BSP_d2off(void) { GPIOA->BSRR = (1U << (TST2_PIN + 16U)); } /*..........................................................................*/ void BSP_d3on(void) { GPIOA->BSRR = (1U << TST3_PIN); } void BSP_d3off(void) { GPIOA->BSRR = (1U << (TST3_PIN + 16U)); } /*..........................................................................*/ void BSP_d4on(void) { GPIOA->BSRR = (1U << TST4_PIN); } void BSP_d4off(void) { GPIOA->BSRR = (1U << (TST4_PIN + 16U)); } /*..........................................................................*/ void BSP_d5on(void) { GPIOA->BSRR = (1U << TST5_PIN); } void BSP_d5off(void) { GPIOA->BSRR = (1U << (TST5_PIN + 16U)); } /*..........................................................................*/ void BSP_d6on(void) { GPIOA->BSRR = (1U << TST6_PIN); } /* LED2 */ void BSP_d6off(void) { GPIOA->BSRR = (1U << (TST6_PIN + 16U)); } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky1(uint8_t num) { /* immutable work events for Blinky1 */ static BlinkyWorkEvt const workBlinky1[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 40U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 30U, .ticks = 7U, } }; DBC_REQUIRE(500, num < ARRAY_NELEM(workBlinky1)); /* must be in range */ return &workBlinky1[num].super; } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky3(uint8_t num) { /* immutable work events for Blinky3 */ static BlinkyWorkEvt const workBlinky3[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 20U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 10U, .ticks = 3U, } }; DBC_REQUIRE(600, num < ARRAY_NELEM(workBlinky3)); /* must be in range */ return &workBlinky3[num].super; } /* SST callbacks ===========================================================*/ void SST_onStart(void) { SystemCoreClockUpdate(); /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ SysTick_Config((SystemCoreClock / BSP_TICKS_PER_SEC) + 1U); /* set priorities of ISRs used in the system */ NVIC_SetPriority(SysTick_IRQn, 0U); /* ... */ } /*..........................................................................*/ void SST_onIdleCond(void) { /* NOTE: called with interrupts DISABLED */ BSP_d6on(); /* turn LED2 on */ #ifdef NDEBUG /* Put the CPU and peripherals to the low-power mode. * you might need to customize the clock management for your application, * see the datasheet for your particular Cortex-M MCU. */ BSP_d6off(); /* turn LED2 off */ __WFI(); /* Wait-For-Interrupt */ BSP_d6on(); /* turn LED2 on */ #endif BSP_d6off(); /* turn LED2 off */ SST_PORT_INT_ENABLE(); /* NOTE: enable interrupts for SS0 */ } ================================================ FILE: sst0_c/examples/blinky_button/button2a.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky_button.h" /* application shared interface */ DBC_MODULE_NAME("button2a") /* for DBC assertions in this module */ /*..........................................................................*/ typedef struct { /* Button2a task */ SST_Task super; /* inherit SST_Task */ /* add internal variables for this AO... */ } Button2a; static void Button2a_ctor(Button2a * const me); static void Button2a_init(Button2a * const me, SST_Evt const * const ie); static void Button2a_dispatch(Button2a * const me, SST_Evt const * const e); /*..........................................................................*/ static Button2a Button2a_inst; /* the Button2a instance */ SST_Task * const AO_Button2a = &Button2a_inst.super; /* opaque AO pointer */ void Button2a_instantiate(void) { Button2a_ctor(&Button2a_inst); } /*..........................................................................*/ static void Button2a_ctor(Button2a * const me) { SST_Task_ctor( &me->super, (SST_Handler)&Button2a_init, (SST_Handler)&Button2a_dispatch); } /*..........................................................................*/ static void Button2a_init(Button2a * const me, SST_Evt const * const ie) { (void)me; (void)ie; } /*..........................................................................*/ static void Button2a_dispatch(Button2a * const me, SST_Evt const * const e) { (void)me; switch (e->sig) { case BUTTON_PRESSED_SIG: { BSP_d4on(); /* Button2a --> Blinky1 */ SST_Task_post(AO_Blinky1, BSP_getWorkEvtBlinky1(1U)); BSP_d4off(); for (uint16_t i = SST_EVT_DOWNCAST(ButtonWorkEvt, e)->toggles; i > 0U; --i) { BSP_d4on(); BSP_d4off(); } break; } case FORWARD_PRESSED_SIG: { BSP_d4on(); /* immutable event can be forwarded to another Task */ SST_Task_post(AO_Button2b, e); /* Button2a --> Button2b */ BSP_d4off(); break; } case BUTTON_RELEASED_SIG: { BSP_d4on(); /* Button2a --> Blinky1 */ SST_Task_post(AO_Blinky1, BSP_getWorkEvtBlinky1(0U)); BSP_d4off(); for (uint16_t i = SST_EVT_DOWNCAST(ButtonWorkEvt, e)->toggles; i > 0U; --i) { BSP_d4on(); BSP_d4off(); } break; } case FORWARD_RELEASED_SIG: { BSP_d4on(); /* immutable event can be forwarded to another Task */ SST_Task_post(AO_Button2b, e); /* Button2a --> Button2b */ BSP_d4off(); break; } default: { DBC_ERROR(500); /* unexpected event */ break; } } } ================================================ FILE: sst0_c/examples/blinky_button/button2b.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky_button.h" /* application shared interface */ DBC_MODULE_NAME("button2b") /* for DBC assertions in this module */ /*..........................................................................*/ typedef struct { /* Button2b task */ SST_Task super; /* inherit SST_Task */ /* add internal variables for this AO... */ } Button2b; static void Button2b_ctor(Button2b * const me); static void Button2b_init(Button2b * const me, SST_Evt const * const e); static void Button2b_dispatch(Button2b * const me, SST_Evt const * const e); /*..........................................................................*/ static Button2b Button2b_inst; /* the Button2b instance */ SST_Task * const AO_Button2b = &Button2b_inst.super; /* opaque AO pointer */ void Button2b_instantiate(void) { Button2b_ctor(&Button2b_inst); } /*..........................................................................*/ static void Button2b_ctor(Button2b * const me) { SST_Task_ctor( &me->super, (SST_Handler)&Button2b_init, (SST_Handler)&Button2b_dispatch); } /*..........................................................................*/ static void Button2b_init(Button2b * const me, SST_Evt const * const ie) { (void)me; (void)ie; } /*..........................................................................*/ static void Button2b_dispatch(Button2b * const me, SST_Evt const * const e) { switch (e->sig) { case FORWARD_PRESSED_SIG: { BSP_d3on(); /* Button2b --> Blinky3 */ SST_Task_post(AO_Blinky3, BSP_getWorkEvtBlinky3(1U)); BSP_d3off(); for (uint16_t i = SST_EVT_DOWNCAST(ButtonWorkEvt, e)->toggles; i > 0U; --i) { BSP_d3on(); BSP_d3off(); } break; } case FORWARD_RELEASED_SIG: { BSP_d3on(); /* Button2b --> Blinky3 */ SST_Task_post(AO_Blinky3, BSP_getWorkEvtBlinky3(0U)); BSP_d3off(); for (uint16_t i = SST_EVT_DOWNCAST(ButtonWorkEvt, e)->toggles; i > 0U; --i) { BSP_d3on(); BSP_d3off(); } break; } default: { DBC_ERROR(500); /* unexpected event */ break; } } } ================================================ FILE: sst0_c/examples/blinky_button/gnu/ek-tm4c123gxl.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST/C) on TM4C123GXL, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-01-25 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f ek-tm4c123gxl.mak # make -f ek-tm4c123gxl.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky_button TARGET := ek-tm4c123gxl #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ sst0.c \ main.c \ blinky1.c \ blinky3.c \ button2a.c \ button2b.c \ bsp_ek-tm4c123gxl.c \ system_TM4C123GH6PM.c \ startup_TM4C123GH6PM.c # C++ source files CPP_SRCS := LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := -DTARGET_IS_TM4C123_RB1 # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m4 ARM_FPU := -mfpu=vfp FLOAT_ABI := -mfloat-abi=softfp #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst0_c/examples/blinky_button/gnu/flash_ek-tm4c123gxl.bat ================================================ ::============================================================================ :: Batch file to program the flash of EK-TM4C123GXL :: :: NOTE: requires the LMFlash programmer (included in QTools for Windows) :: @echo off setlocal @echo Load a given binary file to the flash of EK-TM4C123GXL @echo usage: flash binary-file @echo example: flash dbg\blinky-qk.bin ::---------------------------------------------------------------------------- :: NOTE: The following symbol LMFLASH assumes that LMFlash.exe can :: be found on the PATH. You might need to adjust this symbol to the :: location of the LMFlash utility on your machine :: set LMFLASH=LMFlash.exe if ["%~1"]==[""] ( @echo The binary file missing @goto end ) if not exist %~s1 ( @echo The binary file '%1' does not exist @goto end ) %LMFLASH% -q ek-tm4c123gxl -e -v -r %1 :end endlocal ================================================ FILE: sst0_c/examples/blinky_button/gnu/nucleo-c031c6.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST0/C) on NUCLEO-C031C6, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-02-02 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f nucleo-c031c6.mak # make -f nucleo-c031c6.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky_button TARGET := nucleo-c031c6 #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ sst0.c \ main.c \ blinky1.c \ blinky3.c \ button2a.c \ button2b.c \ bsp_nucleo-c031c6.c \ system_stm32c0xx.c \ startup_stm32c031xx.c # C++ source files CPP_SRCS := LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := -DSTM32C031xx # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m0plus ARM_FPU := FLOAT_ABI := #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst0_c/examples/blinky_button/gnu/nucleo-h743zi.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST0/C) on NUCLEO-H743ZI, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-01-22 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f nucleo-h743zi.mak # make -f nucleo-h743zi.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky_button TARGET := nucleo-h743zi #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ sst0.c \ main.c \ blinky1.c \ blinky3.c \ button2a.c \ button2b.c \ bsp_nucleo-h743zi.c \ startup_stm32h743xx.c \ system_stm32h7xx.c # C++ source files CPP_SRCS := LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := -DSTM32H743xx # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m7 ARM_FPU := -mfpu=fpv5-d16 FLOAT_ABI := -mfloat-abi=softfp #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst0_c/examples/blinky_button/gnu/nucleo-l053r8.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST0/C) on NUCLEO-L053R8, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-01-22 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f nucleo-l053r8.mak # make -f nucleo-l053r8.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky_button TARGET := nucleo-l053r8 #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ sst0.c \ main.c \ blinky1.c \ blinky3.c \ button2a.c \ button2b.c \ bsp_nucleo-l053r8.c \ system_stm32l0xx.c \ startup_stm32l053xx.c # C++ source files CPP_SRCS := LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m0plus ARM_FPU := FLOAT_ABI := #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst0_c/examples/blinky_button/iar/ek-tm4c123gxl.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst0_c/examples/blinky_button/iar/ek-tm4c123gxl.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Application $PROJ_DIR$\..\blinky1.c $PROJ_DIR$\..\blinky3.c $PROJ_DIR$\..\blinky_button.h $PROJ_DIR$\..\bsp.h $PROJ_DIR$\..\bsp_ek-tm4c123gxl.c $PROJ_DIR$\..\button2a.c $PROJ_DIR$\..\button2b.c $PROJ_DIR$\..\main.c ek-tm4c123gxl $PROJ_DIR$\..\..\..\..\3rd_party\ek-tm4c123gxl\iar\startup_TM4C123GH6PM.s $PROJ_DIR$\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c $PROJ_DIR$\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h sst $PROJ_DIR$\..\..\..\src\sst0.c sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.h ================================================ FILE: sst0_c/examples/blinky_button/iar/ek-tm4c123gxl.eww ================================================ $WS_DIR$\ek-tm4c123gxl.ewp ================================================ FILE: sst0_c/examples/blinky_button/iar/nucleo-c031c6.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst0_c/examples/blinky_button/iar/nucleo-c031c6.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Debug Application $PROJ_DIR$\..\blinky1.c $PROJ_DIR$\..\blinky3.c $PROJ_DIR$\..\blinky_button.h $PROJ_DIR$\..\bsp.h $PROJ_DIR$\..\bsp_nucleo-c031c6.c $PROJ_DIR$\..\button2a.c $PROJ_DIR$\..\button2b.c $PROJ_DIR$\..\main.c nucleo-c031c6 $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-c031c6\iar\startup_stm32c031xx.s $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.h sst $PROJ_DIR$\..\..\..\src\sst0.c sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.h ================================================ FILE: sst0_c/examples/blinky_button/iar/nucleo-c031c6.eww ================================================ $WS_DIR$\nucleo-c031c6.ewp ================================================ FILE: sst0_c/examples/blinky_button/iar/nucleo-h743zi.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst0_c/examples/blinky_button/iar/nucleo-h743zi.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Application $PROJ_DIR$\..\blinky1.c $PROJ_DIR$\..\blinky3.c $PROJ_DIR$\..\blinky_button.h $PROJ_DIR$\..\bsp.h $PROJ_DIR$\..\bsp_nucleo-h743zi.c $PROJ_DIR$\..\button2a.c $PROJ_DIR$\..\button2b.c $PROJ_DIR$\..\main.c nucleo-h743zi $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-h743zi\iar\startup_stm32h743xx.s $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-h743zi\stm32h743xx.h $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-h743zi\system_stm32h7xx.c sst $PROJ_DIR$\..\..\..\src\sst0.c sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.h ================================================ FILE: sst0_c/examples/blinky_button/iar/nucleo-h743zi.eww ================================================ $WS_DIR$\nucleo-h743zi.ewp ================================================ FILE: sst0_c/examples/blinky_button/iar/nucleo-l053r8.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst0_c/examples/blinky_button/iar/nucleo-l053r8.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Debug Application $PROJ_DIR$\..\blinky1.c $PROJ_DIR$\..\blinky3.c $PROJ_DIR$\..\blinky_button.h $PROJ_DIR$\..\bsp.h $PROJ_DIR$\..\bsp_nucleo-l053r8.c $PROJ_DIR$\..\button2a.c $PROJ_DIR$\..\button2b.c $PROJ_DIR$\..\main.c nucleo-l053r8 $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\iar\startup_stm32l053xx.s $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c sst $PROJ_DIR$\..\..\..\src\sst0.c sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.h ================================================ FILE: sst0_c/examples/blinky_button/iar/nucleo-l053r8.eww ================================================ $WS_DIR$\nucleo-l053r8.ewp ================================================ FILE: sst0_c/examples/blinky_button/main.c ================================================ /*============================================================================ * Super-Simple Tasker (SST0/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky_button.h" /* application shared interface */ /*..........................................................................*/ int main() { SST_init(); /* initialize the SST kernel */ BSP_init(); /* initialize the Board Support Package */ /* instantiate and start all SST tasks... */ Blinky1_instantiate(); static SST_Evt const *blinky1QSto[10]; /* Event queue storage */ SST_Task_start( AO_Blinky1, /* AO pointer to start */ 1U, /* SST-priority */ blinky1QSto, /* storage for the AO's queue */ ARRAY_NELEM(blinky1QSto), /* queue length */ BSP_getWorkEvtBlinky1(0U)); /* initialization event */ Button2a_instantiate(); static SST_Evt const *button2aQSto[8]; /* Event queue storage */ SST_Task_start( AO_Button2a, /* AO pointer to start */ 2U, /* SST-priority */ button2aQSto, /* storage for the AO's queue */ ARRAY_NELEM(button2aQSto), /* queue length */ (SST_Evt const *)0); /* initialization event -- not used */ Button2b_instantiate(); static SST_Evt const *button2bQSto[6]; /* Event queue storage */ SST_Task_start( AO_Button2b, /* AO pointer to start */ 3U, /* SST-priority */ button2bQSto, /* storage for the AO's queue */ ARRAY_NELEM(button2bQSto), /* queue length */ (SST_Evt const *)0); /* initialization event -- not used */ Blinky3_instantiate(); static SST_Evt const *blinky3QSto[4]; /* Event queue storage */ SST_Task_start( AO_Blinky3, /* AO pointer to start */ 4U, /* SST-priority */ blinky3QSto, /* storage for the AO's queue */ ARRAY_NELEM(blinky3QSto), /* queue length */ BSP_getWorkEvtBlinky3(0U)); /* initialization event */ return SST_Task_run(); /* run the SST tasks */ /* NOTE; in embedded systems SST_Task_run() should not return */ } ================================================ FILE: sst0_c/ports/arm-cm/sst_port.h ================================================ /*============================================================================ * Super-Simple Tasker (SST0/C) port to ARM Cortex-M * * Copyright (C) 2005-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #ifndef SST_PORT_H_ #define SST_PORT_H_ #define SST_PORT_TASK_ATTR SST_TaskPrio prio; #define SST_PORT_MAX_TASK 32U /* SST-PORT disabling/enabling interrupts */ #define SST_PORT_INT_DISABLE() __asm volatile ("cpsid i") #define SST_PORT_INT_ENABLE() __asm volatile ("cpsie i") /* SST-PORT critical section */ #define SST_PORT_CRIT_STAT #define SST_PORT_CRIT_ENTRY() SST_PORT_INT_DISABLE() #define SST_PORT_CRIT_EXIT() SST_PORT_INT_ENABLE() typedef uint32_t SST_ReadySet; /* special idle callback to handle the "idle condition" in SST0 */ void SST_onIdleCond(void); /* the SST scheduler lock key type */ typedef uint32_t SST_LockKey; #if (__ARM_ARCH == 6) /* ARMv6-M? */ /* SST_LOG2() implementation for ARMv6-M (no CLZ instruction) */ static inline uint_fast8_t SST_LOG2(uint32_t x) { static uint8_t const log2LUT[16] = { 0U, 1U, 2U, 2U, 3U, 3U, 3U, 3U, 4U, 4U, 4U, 4U, 4U, 4U, 4U, 4U }; uint_fast8_t n = 0U; SST_ReadySet tmp; #if (SST_PORT_MAX_TASK > 16U) tmp = (SST_ReadySet)(x >> 16U); if (tmp != 0U) { n += 16U; x = tmp; } #endif #if (SST_PORT_MAX_TASK > 8U) tmp = (x >> 8U); if (tmp != 0U) { n += 8U; x = tmp; } #endif tmp = (x >> 4U); if (tmp != 0U) { n += 4U; x = tmp; } return n + log2LUT[x]; } #else /* ARMv7-M+ have CLZ instruction for fast LOG2 computations */ #if defined __ARMCC_VERSION #define SST_LOG2(x_) ((uint_fast8_t)(32U - __builtin_clz((unsigned)(x_)))) #elif defined __GNUC__ #define SST_LOG2(x_) ((uint_fast8_t)(32U - __builtin_clz((unsigned)(x_)))) #elif defined __ICCARM__ #include #define SST_LOG2(x_) ((uint_fast8_t)(32U - __CLZ((unsigned long)(x_)))) #endif /* compiler type */ #endif #endif /* SST_PORT_H_ */ ================================================ FILE: sst0_c/src/sst0.c ================================================ /*=========================================================================== * Super-Simple Tasker (SST0/C) * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ===========================================================================*/ #include "sst.h" /* Super-Simple Tasker (SST) */ #include "dbc_assert.h" /* Design By Contract (DBC) assertions */ DBC_MODULE_NAME("sst0") /* for DBC assertions in this module */ /* bitmask of all SST tasks in the system */ static SST_ReadySet task_readySet; /* array of all SST task pointers in the system */ static SST_Task *task_registry[SST_PORT_MAX_TASK + 1U]; /*..........................................................................*/ void SST_init(void) { } /*..........................................................................*/ int SST_Task_run(void) { SST_onStart(); /* configure and start the interrupts */ SST_PORT_INT_DISABLE(); for (;;) { /* event loop of the SST0 kernel */ if (task_readySet != 0U) { /* any SST tasks ready to run? */ uint_fast8_t const p = SST_LOG2(task_readySet); SST_Task * const task = task_registry[p]; SST_PORT_INT_ENABLE(); /* the task must have some events in the queue */ DBC_ASSERT(100, task->nUsed > 0U); /* get the event out of the queue */ /* NOTE: no critical section because task->tail is accessed only * from this task */ SST_Evt const *e = task->qBuf[task->tail]; if (task->tail == 0U) { /* need to wrap the tail? */ task->tail = task->end; /* wrap around */ } else { --task->tail; } SST_PORT_INT_DISABLE(); if ((--task->nUsed) == 0U) { /* no more events in the queue? */ task_readySet &= ~(1U << (p - 1U)); } SST_PORT_INT_ENABLE(); /* dispatch the received event to the task */ (*task->dispatch)(task, e); /* NOTE: virtual call */ /* TBD: implement event recycling */ } else { /* no SST tasks are ready to run --> idle */ /* SST_onIdleCond() must be called with interrupts DISABLED * because the determination of the idle condition (all event * queues empty) can change at any time by an interrupt posting * events to a queue. * * NOTE: SST_onIdleCond() MUST enable interrupts internally, * ideally at the same time as putting the CPU into a power- * saving mode. */ SST_onIdleCond(); SST_PORT_INT_DISABLE(); /* disable before looping back */ } } #ifdef __GNUC__ /* GNU compiler? */ return 0; #endif } /*..........................................................................*/ void SST_Task_ctor( SST_Task * const me, SST_Handler init, SST_Handler dispatch) { me->init = init; me->dispatch = dispatch; } /*..........................................................................*/ void SST_Task_start( SST_Task * const me, SST_TaskPrio prio, SST_Evt const **qBuf, SST_QCtr qLen, SST_Evt const * const ie) { /*! @pre * - the priority must be in range * - the queue storage must be provided * - the queue length must not be zero * - the priority must not be in use */ DBC_REQUIRE(200, (0U < prio) && (prio <= SST_PORT_MAX_TASK) && (qBuf != (SST_Evt const **)0) && (qLen > 0U) && (task_registry[prio] == (SST_Task *)0)); me->prio = prio; me->qBuf = qBuf; me->end = qLen - 1U; me->head = 0U; me->tail = 0U; me->nUsed = 0U; task_registry[prio] = me; /* initialize this task with the initialization event */ (*me->init)(me, ie); /* NOTE: virtual call */ /* TBD: implement event recycling */ } /*..........................................................................*/ void SST_Task_post(SST_Task * const me, SST_Evt const * const e) { /*! @pre the queue must be sized adequately and cannot overflow */ DBC_REQUIRE(300, me->nUsed <= me->end); SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); me->qBuf[me->head] = e; /* insert event into the queue */ if (me->head == 0U) { /* need to wrap the head? */ me->head = me->end; /* wrap around */ } else { --me->head; } ++me->nUsed; task_readySet |= (1U << (me->prio - 1U)); SST_PORT_CRIT_EXIT(); } /*--------------------------------------------------------------------------*/ static SST_TimeEvt *timeEvt_head = (SST_TimeEvt *)0; /*..........................................................................*/ void SST_TimeEvt_ctor( SST_TimeEvt * const me, SST_Signal sig, SST_Task *task) { me->super.sig = sig; me->task = task; me->ctr = 0U; me->interval = 0U; /* insert time event "me" into the linked-list */ me->next = timeEvt_head; timeEvt_head = me; } /*..........................................................................*/ void SST_TimeEvt_arm( SST_TimeEvt * const me, SST_TCtr ctr, SST_TCtr interval) { SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); me->ctr = ctr; me->interval = interval; SST_PORT_CRIT_EXIT(); } /*..........................................................................*/ bool SST_TimeEvt_disarm(SST_TimeEvt * const me) { SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); bool status = (me->ctr != 0U); me->ctr = 0U; me->interval = 0U; SST_PORT_CRIT_EXIT(); return status; } /*..........................................................................*/ void SST_TimeEvt_tick(void) { for (SST_TimeEvt *t = timeEvt_head; t != (SST_TimeEvt *)0; t = t->next) { SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); if (t->ctr == 0U) { /* disarmed? (most frequent case) */ SST_PORT_CRIT_EXIT(); } else if (t->ctr == 1U) { /* expiring? */ t->ctr = t->interval; SST_PORT_CRIT_EXIT(); SST_Task_post(t->task, &t->super); } else { /* timing out */ --t->ctr; SST_PORT_CRIT_EXIT(); } } } ================================================ FILE: sst0_cpp/README.txt ================================================ This directory contains the non-preemptive SST implementation in C++, referred to as "SST0/C++". - "basic tasks" (non-blocking) - preemptive scheduling - multiple tasks per prioriy level - multiple "activations" per task (event queues) ================================================ FILE: sst0_cpp/examples/README.txt ================================================ This directory contains examples for the non-preemptive SST0/C++ kernel. ================================================ FILE: sst0_cpp/examples/blinky/armclang/nucleo-l053r8.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 nucleo-l053r8 0x4 ARM-ADS 12000000 1 1 0 1 0 1 65535 0 0 0 79 66 8 .\build_nucleo-l053r8\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 UL2CM3 UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM)) 0 ST-LINKIII-KEIL_SWO -U066CFF484951775087074312 -O8431 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P2 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC800 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=1702,853,2113,1355,0)(1007=2082,245,2289,466,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS 1 2 0xE000E400 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 10000000 Application 1 0 0 0 1 1 5 0 0 0 ..\bsp.hpp bsp.hpp 0 0 1 2 8 0 0 0 ..\bsp_nucleo-l053r8.cpp bsp_nucleo-l053r8.cpp 0 0 1 3 8 0 0 0 ..\main.cpp main.cpp 0 0 1 4 8 0 0 0 ..\blinky.cpp blinky.cpp 0 0 1 5 5 0 0 0 ..\blinky.hpp blinky.hpp 0 0 nucleo-l053r8 1 0 0 0 2 6 2 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s startup_stm32l053xx.s 0 0 2 7 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l0xx.h 0 0 2 8 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h stm32l053xx.h 0 0 2 9 1 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c system_stm32l0xx.c 0 0 sst 1 0 0 0 3 10 8 0 0 0 ..\..\..\src\sst0.cpp sst0.cpp 0 0 sst_port 1 0 0 0 4 11 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.hpp sst_port.hpp 0 0
================================================ FILE: sst0_cpp/examples/blinky/armclang/nucleo-l053r8.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
nucleo-l053r8 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32L053R8Tx STMicroelectronics Keil.STM32L0xx_DFP.2.2.0 http://www.keil.com/pack/ IRAM(0x20000000,0x00002000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$Flash\STM32L0xx_64.FLM)) 0 $$Device:STM32L053R8Tx$Device\Include\stm32l0xx.h $$Device:STM32L053R8Tx$SVD\STM32L053x.svd 0 0 0 0 0 0 1 .\build_nucleo-l053r8\ blinky_button 1 0 0 1 1 .\build_nucleo-l053r8\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-l053r8\blinky_button.bin .\build_nucleo-l053r8\blinky_button.axf 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP DARMCM1.DLL -pCM0+ SARMCM3.DLL TARMCM1.DLL -pCM0+ 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M0+" 0 0 0 1 1 0 0 0 0 0 0 0 8 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 1 0x8000000 0x10000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x10000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 0 0x0 0x0 0 0 0 0 1 0 0 0 0 0 4 0 1 0 0 0 3 3 0 0 0 0 0 -Wno-padded .;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-l053r8 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Application bsp.hpp 5 ..\bsp.hpp bsp_nucleo-l053r8.cpp 8 ..\bsp_nucleo-l053r8.cpp main.cpp 8 ..\main.cpp blinky.cpp 8 ..\blinky.cpp blinky.hpp 5 ..\blinky.hpp nucleo-l053r8 startup_stm32l053xx.s 2 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s stm32l0xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l053xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h system_stm32l0xx.c 1 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c sst sst0.cpp 8 ..\..\..\src\sst0.cpp sst_port sst_port.hpp 5 ..\..\..\ports\arm-cm\sst_port.hpp nucleo-l053r8 1
================================================ FILE: sst0_cpp/examples/blinky/blinky.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky.hpp" // application shared interface namespace { DBC_MODULE_NAME("blinky") // for DBC assertions in this module */ } // unnamed namespace namespace App { //............................................................................ class Blinky : public SST::Task { SST::TimeEvt m_te1; SST::TimeEvt m_te2; public: Blinky(void); void init(SST::Evt const * const ie) override; void dispatch(SST::Evt const * const e) override; static Blinky inst; }; //............................................................................ Blinky Blinky::inst; // the Blinky instance SST::Task * const AO_Blinky = &Blinky::inst; // opaque AO pointer //............................................................................ Blinky::Blinky(void) : m_te1(TIMEOUT1_SIG, this), m_te2(TIMEOUT2_SIG, this) {} //............................................................................ void Blinky::init(SST::Evt const * const ie) { static_cast(ie); // unused parameter m_te2.arm(1U, 0U); } //............................................................................ void Blinky::dispatch(SST::Evt const * const e) { switch (e->sig) { case TIMEOUT1_SIG: { BSP::ledOff(); m_te2.arm(BSP::TICKS_PER_SEC*3U/4U, 0U); break; } case TIMEOUT2_SIG: { BSP::ledOn(); m_te1.arm(BSP::TICKS_PER_SEC/4U, 0U); break; } default: { DBC_ERROR(500); // unexpected event break; } } } } // namespace App ================================================ FILE: sst0_cpp/examples/blinky/blinky.hpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #ifndef BLINKY_HPP_ #define BLINKY_HPP_ #include "dbc_assert.h" // Design By Contract (DBC) assertions namespace App { enum Signals { TIMEOUT1_SIG, TIMEOUT2_SIG, // ... MAX_SIG // the last signal }; extern SST::Task * const AO_Blinky; // opaque task pointer } // namespace App #endif // BLINKY_HPP_ ================================================ FILE: sst0_cpp/examples/blinky/bsp.hpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // /// SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #ifndef BSP_HPP_ #define BSP_HPP_ namespace BSP { constexpr std::uint32_t TICKS_PER_SEC = 1000U; void init(void); void ledOn(void); void ledOff(void); } // namespace BSP #endif // BSP_HPP_ ================================================ FILE: sst0_cpp/examples/blinky/bsp_nucleo-l053r8.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST0/C++) Example for STM32 NUCLEO-L053R8 // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // // Copyright (C) 2005 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky.hpp" // application shared interface #include "stm32l0xx.h" // CMSIS-compliant header file for the MCU used // add other drivers if necessary... // Local-scope defines ------------------------------------------------------- namespace { //DBC_MODULE_NAME("bsp_nucleo-l053r8") // for DBC assertions in this module } // unnamed workspace // test pins on GPIO PA #define LED_PIN 5U // ISRs used in the application ============================================== extern "C" { void SysTick_Handler(void); // prototype void SysTick_Handler(void) { // system clock tick ISR SST::TimeEvt::tick(); } // Assertion handler ========================================================= void DBC_fault_handler(char const * const module, int const label) { // // NOTE: add here your application-specific error handling // (void)module; (void)label; // set PRIMASK to disable interrupts and stop SST right here __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { // keep blinking LED2 BSP::ledOn(); // turn LED2 on uint32_t volatile ctr; for (ctr = 10000U; ctr > 0U; --ctr) { } BSP::ledOff(); // turn LED2 off for (ctr = 10000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } //............................................................................ void assert_failed(char const * const module, int const label);// prototype void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } } // extern "C" namespace BSP { // BSP functions ============================================================= void init(void) { // Configure the MPU to prevent NULL-pointer dereferencing // see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu // MPU->RBAR = 0x0U // base address (NULL) | MPU_RBAR_VALID_Msk // valid region | (MPU_RBAR_REGION_Msk & 7U); // region #7 MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region | (0x0U << MPU_RASR_AP_Pos) // no-access region | MPU_RASR_ENABLE_Msk; // region enable MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region | MPU_CTRL_ENABLE_Msk; // enable the MPU __ISB(); __DSB(); // enable GPIO port PA clock RCC->IOPENR |= (1U << 0U); // set all used GPIOA pins as push-pull output, no pull-up, pull-down GPIOA->MODER &= ~(3U << 2U*LED_PIN); GPIOA->MODER |= (1U << 2U*LED_PIN); GPIOA->OTYPER &= ~(1U << LED_PIN); GPIOA->PUPDR &= ~(3U << 2U*LED_PIN); } //............................................................................ void ledOn(void) { GPIOA->BSRR = (1U << LED_PIN); } void ledOff(void) { GPIOA->BSRR = (1U << (LED_PIN + 16U)); } } // namespace BSP // SST callbacks ============================================================= namespace SST { void onStart(void) { SystemCoreClockUpdate(); // set up the SysTick timer to fire at BSP::TICKS_PER_SEC rate SysTick_Config((SystemCoreClock / BSP::TICKS_PER_SEC) + 1U); // set priorities of ISRs used in the system NVIC_SetPriority(SysTick_IRQn, 0U); // ... } //............................................................................ void onIdleCond(void) { // NOTE: called with interrupts DISABLED #ifdef NDEBUG // Put the CPU and peripherals to the low-power mode. // you might need to customize the clock management for your application, // see the datasheet for your particular Cortex-M MCU. // __WFI(); // Wait-For-Interrupt #endif SST_PORT_INT_ENABLE(); // NOTE: enable interrupts for SS0 } } // namespace SST ================================================ FILE: sst0_cpp/examples/blinky/gnu/nucleo-l053r8.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST/C++) on NUCLEO-L053R8, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-01-22 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f nucleo-l053r8.mak # make -f nucleo-l053r8.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky TARGET := nucleo-l053r8 #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ system_stm32l0xx.c \ startup_stm32l053xx.c # C++ source files CPP_SRCS := \ sst0.cpp \ main.cpp \ blinky.cpp \ bsp_nucleo-l053r8.cpp LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m0plus ARM_FPU := FLOAT_ABI := #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-g++ BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst0_cpp/examples/blinky/iar/nucleo-l053r8.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst0_cpp/examples/blinky/iar/nucleo-l053r8.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Debug Application $PROJ_DIR$\..\blinky.cpp $PROJ_DIR$\..\blinky.hpp $PROJ_DIR$\..\bsp.hpp $PROJ_DIR$\..\bsp_nucleo-l053r8.cpp $PROJ_DIR$\..\main.cpp nucleo-l053r8 $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\iar\startup_stm32l053xx.s $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c sst $PROJ_DIR$\..\..\..\src\sst0.cpp sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.hpp ================================================ FILE: sst0_cpp/examples/blinky/iar/nucleo-l053r8.eww ================================================ $WS_DIR$\nucleo-l053r8.ewp ================================================ FILE: sst0_cpp/examples/blinky/main.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST0/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky.hpp" // application shared interface //............................................................................ int main() { SST::init(); // initialize the SST kernel BSP::init(); // initialize the Board Support Package // instantiate and start all SST tasks... static SST::Evt const *blinkyQSto[10]; // Event queue storage App::AO_Blinky->start( 1U, // SST-priority blinkyQSto, // storage for the AO's queue ARRAY_NELEM(blinkyQSto), // queue length nullptr); // initialization event (not used) return SST::Task::run(); // run the SST tasks // NOTE: in embedded systems SST::Task::run() should not return } ================================================ FILE: sst0_cpp/examples/blinky_button/armclang/ek-tm4c123gxl.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 ek-tm4c123gxl 0x4 ARM-ADS 12000000 1 1 1 0 0 1 65535 0 0 0 79 66 8 .\build_ek-tm4c123gxl\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 4 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 0 0 19 BIN\lmidk-agdi.dll 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 UL2CM3 UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0TM4C123_256 -FL040000 -FS00 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM) 0 DLGTARM (1010=1120,219,1570,776,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=1881,651,2358,966,0) 0 ARMDBGFLAGS 0 lmidk-agdi -U0E10259B -O4686 -S5 -FO29 0 0 247 1
2900
0 0 0 0 0 1 C:\GitHub\Super-Simple-Tasker\sst0_cpp\examples\blinky_button\bsp_ek-tm4c123gxl.c \\build_ek_tm4c123gxl\../bsp_ek-tm4c123gxl.c\247
1 2 0x20000200 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Applicatioin 1 0 0 0 1 1 5 0 0 0 ..\bsp.hpp bsp.hpp 0 0 1 2 8 0 0 0 ..\bsp_ek-tm4c123gxl.cpp bsp_ek-tm4c123gxl.cpp 0 0 1 3 8 0 0 0 ..\button2a.cpp button2a.cpp 0 0 1 4 8 0 0 0 ..\button2b.cpp button2b.cpp 0 0 1 5 8 0 0 0 ..\main.cpp main.cpp 0 0 1 6 5 0 0 0 ..\blinky_button.hpp blinky_button.hpp 0 0 1 7 8 0 0 0 ..\blinky1.cpp blinky1.cpp 0 0 1 8 8 0 0 0 ..\blinky3.cpp blinky3.cpp 0 0 ek-tm4c123gxl 1 0 0 0 2 9 2 0 0 0 ..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s startup_TM4C123GH6PM.s 0 0 2 10 1 0 0 0 ..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c system_TM4C123GH6PM.c 0 0 2 11 5 0 0 0 ..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h TM4C123GH6PM.h 0 0 sst 1 0 0 0 3 12 8 0 0 0 ..\..\..\src\sst0.cpp sst0.cpp 0 0 sst_port 1 0 0 0 4 13 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.hpp sst_port.hpp 0 0
================================================ FILE: sst0_cpp/examples/blinky_button/armclang/ek-tm4c123gxl.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
ek-tm4c123gxl 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 TM4C123GH6PM Texas Instruments Keil.TM4C_DFP.1.1.0 http://www.keil.com/pack/ IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0TM4C123_256 -FS00 -FL040000 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM)) 0 $$Device:TM4C123GH6PM$Device\Include\TM4C123\TM4C123.h $$Device:TM4C123GH6PM$SVD\TM4C123\TM4C123GH6PM.svd 0 0 0 0 0 0 1 .\build_ek-tm4c123gxl\ blinky_button 1 0 0 1 1 .\build_ek-tm4c123gxl\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_ek-tm4c123gxl\blinky_button.bin .\build_ek-tm4c123gxl\blinky_button.axf 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -MPU DCM.DLL -pCM4 SARMCM3.DLL -MPU TCM.DLL -pCM4 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL "" () 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M4" 0 0 0 1 1 0 0 2 0 0 0 0 8 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x8000 1 0x0 0x40000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x40000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x8000 0 0x0 0x0 0 1 0 0 1 0 0 0 0 0 3 0 1 0 0 0 3 3 0 0 0 0 0 __FPU_PRESENT ..;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\ek-tm4c123gxl 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Applicatioin bsp.hpp 5 ..\bsp.hpp bsp_ek-tm4c123gxl.cpp 8 ..\bsp_ek-tm4c123gxl.cpp button2a.cpp 8 ..\button2a.cpp button2b.cpp 8 ..\button2b.cpp main.cpp 8 ..\main.cpp blinky_button.hpp 5 ..\blinky_button.hpp blinky1.cpp 8 ..\blinky1.cpp blinky3.cpp 8 ..\blinky3.cpp ek-tm4c123gxl startup_TM4C123GH6PM.s 2 ..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s system_TM4C123GH6PM.c 1 ..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c TM4C123GH6PM.h 5 ..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h sst sst0.cpp 8 ..\..\..\src\sst0.cpp sst_port sst_port.hpp 5 ..\..\..\ports\arm-cm\sst_port.hpp ek-tm4c123gxl 1
================================================ FILE: sst0_cpp/examples/blinky_button/armclang/nucleo-c031c6.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 nucleo-c031c6 0x4 ARM-ADS 12000000 1 1 0 1 0 1 65535 0 0 0 79 66 8 .\build_nucleo-c031c6\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 ST-LINKIII-KEIL_SWO -U-O206 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 UL2CM3 UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) 0 lmidk-agdi -U0E10259B -O4622 -S3 -FO29 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=1150,195,1600,752,0)(1007=-1,-1,-1,-1,0)(1008=1224,174,1600,410,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS 0 0 120 1
134219768
0 0 0 0 0 1 C:\GitHub\Super-Simple-Tasker\sst_cpp\examples\blinky_button\bsp_nucleo-c031c6.c \\blinky_button\../bsp_nucleo-c031c6.c\120
1 0 0 1
134221496
0 0 0 0 0 1
0 1 OS_curr 1 1 OS_next 2 1 OS_readySet 1 2 0x200000f0 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 2 10000000
Application 1 0 0 0 1 1 5 0 0 0 ..\blinky_button.hpp blinky_button.hpp 0 0 1 2 8 0 0 0 ..\blinky1.cpp blinky1.cpp 0 0 1 3 8 0 0 0 ..\blinky3.cpp blinky3.cpp 0 0 1 4 5 0 0 0 ..\bsp.hpp bsp.hpp 0 0 1 5 8 0 0 0 ..\bsp_nucleo-c031c6.cpp bsp_nucleo-c031c6.cpp 0 0 1 6 8 0 0 0 ..\button2a.cpp button2a.cpp 0 0 1 7 8 0 0 0 ..\button2b.cpp button2b.cpp 0 0 1 8 8 0 0 0 ..\main.cpp main.cpp 0 0 nucleo-c031c6 1 0 0 0 2 9 5 0 0 0 ..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h stm32c031xx.h 0 0 2 10 1 0 0 0 ..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c system_stm32c0xx.c 0 0 2 11 2 0 0 0 ..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s startup_stm32c031xx.s 0 0 sst 1 0 0 0 3 12 8 0 0 0 ..\..\..\src\sst0.cpp sst0.cpp 0 0 sst_port 1 0 0 0 4 13 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.hpp sst_port.hpp 0 0
================================================ FILE: sst0_cpp/examples/blinky_button/armclang/nucleo-c031c6.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
nucleo-c031c6 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32C031C6Tx STMicroelectronics Keil.STM32C0xx_DFP.1.0.0 https://www.keil.com/pack/ IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) 0 $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd 0 0 0 0 0 0 1 .\build_nucleo-c031c6\ blinky_button 1 0 0 1 1 .\build_nucleo-c031c6\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-c031c6\blinky_button.bin .\build_nucleo-c031c6\blinky_button.axf 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP-MPU DARMCM1.DLL -pCM0+ SARMCM3.DLL -MPU TARMCM1.DLL -pCM0+ 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL "" () 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M0+" 0 0 0 1 1 0 0 0 0 0 0 0 8 1 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x3000 1 0x8000000 0x8000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x8000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x3000 0 0x0 0x0 0 0 0 0 1 0 0 0 0 0 3 0 1 1 0 0 3 3 0 0 0 0 0 -Wconditional-uninitialized -Wsometimes-uninitialized .;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-c031c6 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Application blinky_button.hpp 5 ..\blinky_button.hpp blinky1.cpp 8 ..\blinky1.cpp blinky3.cpp 8 ..\blinky3.cpp bsp.hpp 5 ..\bsp.hpp bsp_nucleo-c031c6.cpp 8 ..\bsp_nucleo-c031c6.cpp button2a.cpp 8 ..\button2a.cpp button2b.cpp 8 ..\button2b.cpp main.cpp 8 ..\main.cpp nucleo-c031c6 stm32c031xx.h 5 ..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h system_stm32c0xx.c 1 ..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c startup_stm32c031xx.s 2 ..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s sst sst0.cpp 8 ..\..\..\src\sst0.cpp sst_port sst_port.hpp 5 ..\..\..\ports\arm-cm\sst_port.hpp ek-tm4c123gxl 1
================================================ FILE: sst0_cpp/examples/blinky_button/armclang/nucleo-h743zi.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 arm-nucleo-h743zi 0x4 ARM-ADS 12000000 1 1 1 0 0 1 65535 0 0 0 79 66 8 .\build_nucleo-h743zi\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 0 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 UL2CM3 UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0STM32H7x_2048 -FL0200000 -FS08000000 -FP0($$Device:STM32H743ZITx$CMSIS\Flash\STM32H7x_2048.FLM) 0 ST-LINKIII-KEIL_SWO -U0675FF504955857567065746 -O8399 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P2 -N00("ARM CoreSight SW-DP (ARM Core") -D00(6BA02477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20010000 -FC1000 -FN1 -FF0STM32H7x_2048.FLM -FS08000000 -FL0200000 -FP0($$Device:STM32H743ZITx$CMSIS\Flash\STM32H7x_2048.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=1221,723,1671,1280,0)(6017=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(6016=-1,-1,-1,-1,0)(1012=3268,1338,3745,1653,0) 0 ARMDBGFLAGS 0 1 task_readySet 1 2 0xE000ED08 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 10000000 Applicatioin 1 0 0 0 1 1 5 0 0 0 ..\blinky_button.hpp blinky_button.hpp 0 0 1 2 8 0 0 0 ..\blinky1.cpp blinky1.cpp 0 0 1 3 8 0 0 0 ..\blinky3.cpp blinky3.cpp 0 0 1 4 5 0 0 0 ..\bsp.hpp bsp.hpp 0 0 1 5 8 0 0 0 ..\bsp_nucleo-h743zi.cpp bsp_nucleo-h743zi.cpp 0 0 1 6 8 0 0 0 ..\button2a.cpp button2a.cpp 0 0 1 7 8 0 0 0 ..\button2b.cpp button2b.cpp 0 0 1 8 8 0 0 0 ..\main.cpp main.cpp 0 0 nucleo-h743zi 1 0 0 0 2 9 2 0 0 0 ..\..\..\..\3rd_party\nucleo-h743zi\arm\startup_stm32h743xx.s startup_stm32h743xx.s 0 0 2 10 5 0 0 0 ..\..\..\..\3rd_party\nucleo-h743zi\stm32h743xx.h stm32h743xx.h 0 0 2 11 1 0 0 0 ..\..\..\..\3rd_party\nucleo-h743zi\system_stm32h7xx.c system_stm32h7xx.c 0 0 sst 1 0 0 0 3 12 8 0 0 0 ..\..\..\src\sst0.cpp sst0.cpp 0 0 sst_port 1 0 0 0 4 13 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.hpp sst_port.hpp 0 0
================================================ FILE: sst0_cpp/examples/blinky_button/armclang/nucleo-h743zi.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
arm-nucleo-h743zi 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32H743ZITx STMicroelectronics Keil.STM32H7xx_DFP.3.0.0 http://www.keil.com/pack/ IRAM(0x20000000,0x00020000) IRAM2(0x24000000,0x00080000) IROM(0x08000000,0x00200000) CPUTYPE("Cortex-M7") FPU3(DFPU) CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32H7x_2048 -FS08000000 -FL0200000 -FP0($$Device:STM32H743ZITx$CMSIS\Flash\STM32H7x_2048.FLM)) 0 $$Device:STM32H743ZITx$Drivers\CMSIS\Device\ST\STM32H7xx\Include\stm32h7xx.h $$Device:STM32H743ZITx$CMSIS\SVD\STM32H7x3.svd 0 0 0 0 0 0 1 .\build_nucleo-h743zi\ blinky_button 1 0 0 1 1 .\build_nucleo-h743zi\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-h743zi\blinky_button.bin .\build_nucleo-h743zi\blinky_button.axf 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP -MPU DCM.DLL -pCM7 SARMCM3.DLL -MPU TCM.DLL -pCM7 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL "" () 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M7" 0 0 0 1 1 0 0 3 0 0 1 0 8 0 0 0 0 3 4 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x20000 1 0x8000000 0x200000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x200000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x20000 0 0x24000000 0x80000 0 1 0 0 1 0 0 0 0 0 3 0 1 0 0 0 3 3 0 0 0 0 0 STM32H743xx .;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-h743zi 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Applicatioin blinky_button.hpp 5 ..\blinky_button.hpp blinky1.cpp 8 ..\blinky1.cpp blinky3.cpp 8 ..\blinky3.cpp bsp.hpp 5 ..\bsp.hpp bsp_nucleo-h743zi.cpp 8 ..\bsp_nucleo-h743zi.cpp button2a.cpp 8 ..\button2a.cpp button2b.cpp 8 ..\button2b.cpp main.cpp 8 ..\main.cpp nucleo-h743zi startup_stm32h743xx.s 2 ..\..\..\..\3rd_party\nucleo-h743zi\arm\startup_stm32h743xx.s stm32h743xx.h 5 ..\..\..\..\3rd_party\nucleo-h743zi\stm32h743xx.h system_stm32h7xx.c 1 ..\..\..\..\3rd_party\nucleo-h743zi\system_stm32h7xx.c sst sst0.cpp 8 ..\..\..\src\sst0.cpp sst_port sst_port.hpp 5 ..\..\..\ports\arm-cm\sst_port.hpp nucleo-h743zi 1
================================================ FILE: sst0_cpp/examples/blinky_button/armclang/nucleo-l053r8.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 nucleo-l053r8 0x4 ARM-ADS 12000000 1 1 0 1 0 1 65535 0 0 0 79 66 8 .\build_nucleo-l053r8\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 UL2CM3 UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM)) 0 ST-LINKIII-KEIL_SWO -U066CFF484951775087074312 -O8431 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P2 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC800 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=1702,853,2113,1355,0)(1007=2082,245,2289,466,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS 1 2 0xE000E400 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 10000000 Application 1 0 0 0 1 1 5 0 0 0 ..\blinky_button.hpp blinky_button.hpp 0 0 1 2 8 0 0 0 ..\blinky1.cpp blinky1.cpp 0 0 1 3 8 0 0 0 ..\blinky3.cpp blinky3.cpp 0 0 1 4 5 0 0 0 ..\bsp.hpp bsp.hpp 0 0 1 5 8 0 0 0 ..\bsp_nucleo-l053r8.cpp bsp_nucleo-l053r8.cpp 0 0 1 6 8 0 0 0 ..\button2a.cpp button2a.cpp 0 0 1 7 8 0 0 0 ..\button2b.cpp button2b.cpp 0 0 1 8 8 0 0 0 ..\main.cpp main.cpp 0 0 nucleo-l053r8 1 0 0 0 2 9 2 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s startup_stm32l053xx.s 0 0 2 10 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l0xx.h 0 0 2 11 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h stm32l053xx.h 0 0 2 12 1 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c system_stm32l0xx.c 0 0 sst 1 0 0 0 3 13 8 0 0 0 ..\..\..\src\sst0.cpp sst0.cpp 0 0 sst_port 1 0 0 0 4 14 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.hpp sst_port.hpp 0 0
================================================ FILE: sst0_cpp/examples/blinky_button/armclang/nucleo-l053r8.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
nucleo-l053r8 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32L053R8Tx STMicroelectronics Keil.STM32L0xx_DFP.2.2.0 http://www.keil.com/pack/ IRAM(0x20000000,0x00002000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$Flash\STM32L0xx_64.FLM)) 0 $$Device:STM32L053R8Tx$Device\Include\stm32l0xx.h $$Device:STM32L053R8Tx$SVD\STM32L053x.svd 0 0 0 0 0 0 1 .\build_nucleo-l053r8\ blinky_button 1 0 0 1 1 .\build_nucleo-l053r8\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-l053r8\blinky_button.bin .\build_nucleo-l053r8\blinky_button.axf 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP DARMCM1.DLL -pCM0+ SARMCM3.DLL TARMCM1.DLL -pCM0+ 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M0+" 0 0 0 1 1 0 0 0 0 0 0 0 8 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 1 0x8000000 0x10000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x10000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 0 0x0 0x0 0 0 0 0 1 0 0 0 0 0 4 0 1 0 0 0 3 3 0 0 0 0 0 -Wno-padded .;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-l053r8 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Application blinky_button.hpp 5 ..\blinky_button.hpp blinky1.cpp 8 ..\blinky1.cpp blinky3.cpp 8 ..\blinky3.cpp bsp.hpp 5 ..\bsp.hpp bsp_nucleo-l053r8.cpp 8 ..\bsp_nucleo-l053r8.cpp button2a.cpp 8 ..\button2a.cpp button2b.cpp 8 ..\button2b.cpp main.cpp 8 ..\main.cpp nucleo-l053r8 startup_stm32l053xx.s 2 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s stm32l0xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l053xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h system_stm32l0xx.c 1 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c sst sst0.cpp 8 ..\..\..\src\sst0.cpp sst_port sst_port.hpp 5 ..\..\..\ports\arm-cm\sst_port.hpp nucleo-l053r8 1
================================================ FILE: sst0_cpp/examples/blinky_button/blinky1.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST0/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface namespace { DBC_MODULE_NAME("blinky1") // for DBC assertions in this module */ } // unnamed namespace namespace App { //............................................................................ class Blinky1 : public SST::Task { SST::TimeEvt m_te; std::uint16_t m_toggles; public: Blinky1(void); void init(SST::Evt const * const ie) override; void dispatch(SST::Evt const * const e) override; static Blinky1 inst; }; //............................................................................ Blinky1 Blinky1::inst; // the Blinky1 instance SST::Task * const AO_Blinky1 = &Blinky1::inst; // opaque AO pointer //............................................................................ Blinky1::Blinky1(void) : m_te(TIMEOUT_SIG, this) {} //............................................................................ void Blinky1::init(SST::Evt const * const ie) { /* the initial event must be provided and must be WORKLOAD_SIG */ DBC_REQUIRE(300, (ie != nullptr) && (ie->sig == BLINKY_WORK_SIG)); m_te.arm( SST::evt_downcast(ie)->ticks, SST::evt_downcast(ie)->ticks); m_toggles = SST::evt_downcast(ie)->toggles; } //............................................................................ void Blinky1::dispatch(SST::Evt const * const e) { switch (e->sig) { case TIMEOUT_SIG: { for (std::uint16_t i = m_toggles; i > 0U; --i) { // SST scheduler lock is not needed in non-preemptive SST0 //SST::LockKey key = lock(3U); BSP::d5on(); BSP::d5off(); //unlock(key); } break; } case BLINKY_WORK_SIG: { BSP::d5on(); m_te.arm( SST::evt_downcast(e)->ticks, SST::evt_downcast(e)->ticks); m_toggles = SST::evt_downcast(e)->toggles; BSP::d5off(); break; } default: { DBC_ERROR(500); // unexpected event break; } } } } // namespace App ================================================ FILE: sst0_cpp/examples/blinky_button/blinky3.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface namespace { DBC_MODULE_NAME("blinky3") // for DBC assertions in this module } // unnamed namespace namespace App { //............................................................................ class Blinky3 : public SST::Task { SST::TimeEvt m_te; std::uint16_t m_toggles; public: Blinky3(void); void init(SST::Evt const * const ie) override; void dispatch(SST::Evt const * const e) override; static Blinky3 inst; }; //............................................................................ Blinky3 Blinky3::inst; // the Blinky3 instance SST::Task * const AO_Blinky3 = &Blinky3::inst; // opaque AO pointer //............................................................................ Blinky3::Blinky3(void) : m_te(TIMEOUT_SIG, this) {} //............................................................................ void Blinky3::init(SST::Evt const * const ie) { // the initial event must be provided and must be WORKLOAD_SIG DBC_REQUIRE(300, (ie != nullptr) && (ie->sig == BLINKY_WORK_SIG)); m_te.arm( SST::evt_downcast(ie)->ticks, SST::evt_downcast(ie)->ticks); m_toggles = SST::evt_downcast(ie)->toggles; } //............................................................................ void Blinky3::dispatch(SST::Evt const * const e) { switch (e->sig) { case TIMEOUT_SIG: { for (std::uint16_t i = m_toggles; i > 0U; --i) { BSP::d2on(); BSP::d2off(); } break; } case BLINKY_WORK_SIG: { BSP::d2on(); m_te.arm( SST::evt_downcast(e)->ticks, SST::evt_downcast(e)->ticks); m_toggles = SST::evt_downcast(e)->toggles; BSP::d2off(); break; } default: { DBC_ERROR(500); // unexpected event break; } } } } // namespace App ================================================ FILE: sst0_cpp/examples/blinky_button/blinky_button.hpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #ifndef BLINKY_BUTTON_HPP_ #define BLINKY_BUTTON_HPP_ #include "dbc_assert.h" // Design By Contract (DBC) assertions namespace App { enum Signals { TIMEOUT_SIG, BUTTON_PRESSED_SIG, BUTTON_RELEASED_SIG, BLINKY_WORK_SIG, FORWARD_PRESSED_SIG, FORWARD_RELEASED_SIG, // ... MAX_SIG // the last signal }; // event with parameters struct BlinkyWorkEvt { SST::Evt super; std::uint16_t toggles; // number of toggles of the signal std::uint8_t ticks; // number of clock ticks between }; // event with parameters struct ButtonWorkEvt { SST::Evt super; std::uint16_t toggles; // number of toggles of the signal }; extern SST::Task * const AO_Blinky1; // opaque task pointer extern SST::Task * const AO_Blinky3; // opaque task pointer extern SST::Task * const AO_Button2a; // opaque task pointer extern SST::Task * const AO_Button2b; // opaque task pointer } // namespace App #endif // BLINKY_BUTTON_HPP_ ================================================ FILE: sst0_cpp/examples/blinky_button/bsp.hpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // /// SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #ifndef BSP_HPP_ #define BSP_HPP_ namespace BSP { constexpr std::uint32_t TICKS_PER_SEC = 1000U; void init(void); void d1on(void); void d1off(void); void d2on(void); void d2off(void); void d3on(void); void d3off(void); void d4on(void); void d4off(void); void d5on(void); void d5off(void); void d6on(void); void d6off(void); // immutable events for Blinky tasks SST::Evt const *getWorkEvtBlinky1(std::uint8_t num); SST::Evt const *getWorkEvtBlinky3(std::uint8_t num); } // namespace BSP #endif // BSP_HPP_ ================================================ FILE: sst0_cpp/examples/blinky_button/bsp_ek-tm4c123gxl.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST0/C++) Example for TivaC TM4C123GXL // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // // Copyright (C) 2005 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface #include "TM4C123GH6PM.h" // the device specific header (TI) #include // to exercise the FPU // add other drivers if necessary... // Local-scope defines ------------------------------------------------------- namespace { DBC_MODULE_NAME("bsp_ek-tm4c123gxl") // for DBC assertions in this module } // unnamed workspace /* test pins on GPIOF */ #define TST1_PIN (1U << 1U) /* LED Red */ #define TST2_PIN (1U << 2U) /* LED Blue */ /* test pins on GPIOD */ #define TST3_PIN (1U << 0U) #define TST4_PIN (1U << 1U) #define TST5_PIN (1U << 2U) /* test pins on GPIOF */ #define TST6_PIN (1U << 3U) /* LED Green */ /* Button on the board on GPIOF */ #define BTN_SW1 (1U << 4) // ISRs used in the application ============================================== extern "C" { void SysTick_Handler(void) { // system clock tick ISR BSP::d1on(); SST::TimeEvt::tick(); // get state of the user button // Perform the debouncing of buttons. The algorithm for debouncing // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle // and Michael Barr, page 71. // static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = ~GPIOF_AHB->DATA_Bits[BTN_SW1]; uint32_t tmp = buttons.depressed; // save the debounced depressed buttons.depressed |= (buttons.previous & current); // set depressed buttons.depressed &= (buttons.previous | current); // clear released buttons.previous = current; // update the history tmp ^= buttons.depressed; // changed debounced depressed if ((tmp & BTN_SW1) != 0U) { /* debounced SW1 state changed? */ if ((buttons.depressed & BTN_SW1) != 0U) { /* is SW1 depressed? */ // immutable button-press event static App::ButtonWorkEvt const pressEvt = { { App::BUTTON_PRESSED_SIG }, 60U }; // immutable forward-press event static App::ButtonWorkEvt const fPressEvt = { { App::FORWARD_PRESSED_SIG }, 60U }; App::AO_Button2a->post(&fPressEvt.super); App::AO_Button2a->post(&pressEvt.super); } else { // B1 is released // immutable button-release event static App::ButtonWorkEvt const releaseEvt = { { App::BUTTON_RELEASED_SIG }, 80U }; // immutable forward-release event static App::ButtonWorkEvt const fReleaseEvt = { { App::FORWARD_RELEASED_SIG }, 80U }; App::AO_Button2a->post(&fReleaseEvt.super); App::AO_Button2a->post(&releaseEvt.super); } } BSP::d1off(); } // Assertion handler ========================================================= void DBC_fault_handler(char const * const module, int const label) { // // NOTE: add here your application-specific error handling // (void)module; (void)label; // set PRIMASK to disable interrupts and stop SST right here __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { // keep blinking LED2 BSP::d6on(); // turn LED2 on uint32_t volatile ctr; for (ctr = 1000000U; ctr > 0U; --ctr) { } BSP::d6off(); // turn LED2 off for (ctr = 1000000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } //............................................................................ void assert_failed(char const * const module, int const label);// prototype void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } } // extern "C" namespace BSP { // BSP functions ============================================================= void init(void) { // Configure the MPU to prevent NULL-pointer dereferencing // see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu // MPU->RBAR = 0x0U // base address (NULL) | MPU_RBAR_VALID_Msk // valid region | (MPU_RBAR_REGION_Msk & 7U); // region #7 MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region | (0x0U << MPU_RASR_AP_Pos) // no-access region | MPU_RASR_ENABLE_Msk; // region enable MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region | MPU_CTRL_ENABLE_Msk; // enable the MPU __ISB(); __DSB(); SYSCTL->RCGCGPIO |= (1U << 5U); /* enable Run mode for GPIOF */ SYSCTL->RCGCGPIO |= (1U << 3U); /* enable Run mode for GPIOD */ __ISB(); __DSB(); SYSCTL->GPIOHBCTL |= (1U << 5); /* enable AHB for GPIOF */ SYSCTL->GPIOHBCTL |= (1U << 3); /* enable AHB for GPIOD */ __ISB(); __DSB(); /* configure test pins on GPIOF (digital output) */ GPIOF_AHB->DIR |= (TST1_PIN | TST2_PIN | TST6_PIN); GPIOF_AHB->DEN |= (TST1_PIN | TST2_PIN | TST6_PIN); /* configure button on GPIOF (digital input) */ GPIOF_AHB->DIR &= ~(BTN_SW1); /* input */ GPIOF_AHB->DEN |= (BTN_SW1); /* digital enable */ GPIOF_AHB->PUR |= (BTN_SW1); /* pull-up resistor enable */ /* configure test pins on GPIOD (digital output) */ GPIOD_AHB->DIR |= (TST3_PIN | TST4_PIN | TST5_PIN); GPIOD_AHB->DEN |= (TST3_PIN | TST4_PIN | TST5_PIN); } //............................................................................ #if defined __ARMCC_VERSION #elif defined __GNUC__ std::uint32_t __errno; // GNU-ARM needs this to link sqrtf() #endif static void exerciseFPU(float x) { // exercise the single-precision FPU by calculating the identity: // sqrt(x) == x / sqrt(x) for x > 0 // float tmp1 = sqrtf(x); // single-precision sqrt() float tmp2 = x / tmp1; DBC_ENSURE(200, (tmp1 - 1e-4f <= tmp2) && (tmp2 <= tmp1 + 1e-4f)); } //............................................................................ void d1on(void) { // LED-Red */ GPIOF_AHB->DATA_Bits[TST1_PIN] = 0xFFU; // don't use the FPU in the ISR } void d1off(void) { GPIOF_AHB->DATA_Bits[TST1_PIN] = 0x00U; } //............................................................................ void d2on(void) { /* LED-Blue */ GPIOF_AHB->DATA_Bits[TST2_PIN] = 0xFFU; exerciseFPU(1.2345f); } void d2off(void) { GPIOF_AHB->DATA_Bits[TST2_PIN] = 0x00U; } //............................................................................ void d3on(void) { GPIOD_AHB->DATA_Bits[TST3_PIN] = 0xFFU; exerciseFPU(0.345f); } void d3off(void) { GPIOD_AHB->DATA_Bits[TST3_PIN] = 0x00U; } //............................................................................ void d4on(void) { GPIOD_AHB->DATA_Bits[TST4_PIN] = 0xFFU; exerciseFPU(0.456f); } void d4off(void) { GPIOD_AHB->DATA_Bits[TST4_PIN] = 0x00U; } //............................................................................ void d5on(void) { GPIOD_AHB->DATA_Bits[TST5_PIN] = 0xFFU; exerciseFPU(1.567f); } void d5off(void) { GPIOD_AHB->DATA_Bits[TST5_PIN] = 0x00U; } //............................................................................ void d6on(void) { /* LED2-Green */ GPIOF_AHB->DATA_Bits[TST6_PIN] = 0xFFU; exerciseFPU(1.2345f); } void d6off(void) { GPIOF_AHB->DATA_Bits[TST6_PIN] = 0x00U; } //............................................................................ SST::Evt const *getWorkEvtBlinky1(uint8_t num) { // immutable work events for Blinky1 static App::BlinkyWorkEvt const workBlinky1[] = { { { App::BLINKY_WORK_SIG }, 40U, 5U }, { { App::BLINKY_WORK_SIG }, 30U, 7U } }; DBC_REQUIRE(500, num < ARRAY_NELEM(workBlinky1)); // num must be in range return &workBlinky1[num].super; } //............................................................................ SST::Evt const *getWorkEvtBlinky3(uint8_t num) { // immutable work events for Blinky3 static App::BlinkyWorkEvt const workBlinky3[] = { { { App::BLINKY_WORK_SIG }, 20U, 5U }, { { App::BLINKY_WORK_SIG }, 10U, 3U } }; DBC_REQUIRE(600, num < ARRAY_NELEM(workBlinky3)); // num must be in range return &workBlinky3[num].super; } } // namespace BSP // SST callbacks ============================================================= namespace SST { void onStart(void) { SystemCoreClockUpdate(); // set up the SysTick timer to fire at BSP::TICKS_PER_SEC rate SysTick_Config((SystemCoreClock / BSP::TICKS_PER_SEC) + 1U); // set priorities of ISRs used in the system NVIC_SetPriority(SysTick_IRQn, 0U); // ... } //............................................................................ void onIdleCond(void) { // NOTE: called with interrupts DISABLED BSP::d6on(); // turn LED-Green on #ifdef NDEBUG // Put the CPU and peripherals to the low-power mode. // you might need to customize the clock management for your application, // see the datasheet for your particular Cortex-M MCU. // BSP::d6off(); // turn LED-Green off __WFI(); // Wait-For-Interrupt BSP::d6on(); // turn LED-Green on #else #endif BSP::d6off(); // turn LED-Green off SST_PORT_INT_ENABLE(); // NOTE: enable interrupts for SS0 } } // namespace SST ================================================ FILE: sst0_cpp/examples/blinky_button/bsp_nucleo-c031c6.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST0/C++) Example for STM32 NUCLEO-C031C6 // // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // // Copyright (C) 2005 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface #include "stm32c0xx.h" // CMSIS-compliant header file for the MCU used // add other drivers if necessary... // Local-scope defines ------------------------------------------------------- namespace { DBC_MODULE_NAME("bsp_nucleo-c031c6") // for DBC assertions in this module } // unnamed workspace // test pins on GPIO PA #define TST1_PIN 7U #define TST2_PIN 6U #define TST3_PIN 4U #define TST4_PIN 1U #define TST5_PIN 0U #define TST6_PIN 5U /* LED L4-Green */ // buttons on GPIO PC #define B1_PIN 13U // ISRs used in the application ============================================== extern "C" { void SysTick_Handler(void); // prototype void SysTick_Handler(void) { // system clock tick ISR BSP::d1on(); SST::TimeEvt::tick(); // get state of the user button // Perform the debouncing of buttons. The algorithm for debouncing // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle // and Michael Barr, page 71. // static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = ~GPIOC->IDR; // read GPIO PortC uint32_t tmp = buttons.depressed; // save the debounced depressed buttons.depressed |= (buttons.previous & current); // set depressed buttons.depressed &= (buttons.previous | current); // clear released buttons.previous = current; // update the history tmp ^= buttons.depressed; // changed debounced depressed if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? if ((buttons.depressed & (1U << B1_PIN)) != 0U) { // depressed? // immutable button-press event static App::ButtonWorkEvt const pressEvt = { { App::BUTTON_PRESSED_SIG }, 60U }; // immutable forward-press event static App::ButtonWorkEvt const fPressEvt = { { App::FORWARD_PRESSED_SIG }, 60U }; App::AO_Button2a->post(&fPressEvt.super); App::AO_Button2a->post(&pressEvt.super); } else { // B1 is released // immutable button-release event static App::ButtonWorkEvt const releaseEvt = { { App::BUTTON_RELEASED_SIG }, 80U }; // immutable forward-release event static App::ButtonWorkEvt const fReleaseEvt = { { App::FORWARD_RELEASED_SIG }, 80U }; App::AO_Button2a->post(&fReleaseEvt.super); App::AO_Button2a->post(&releaseEvt.super); } } BSP::d1off(); } // Assertion handler ========================================================= void DBC_fault_handler(char const * const module, int const label) { // // NOTE: add here your application-specific error handling // (void)module; (void)label; // set PRIMASK to disable interrupts and stop SST right here __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { // keep blinking LED2 BSP::d6on(); // turn LED2 on uint32_t volatile ctr; for (ctr = 10000U; ctr > 0U; --ctr) { } BSP::d6off(); // turn LED2 off for (ctr = 10000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } //............................................................................ void assert_failed(char const * const module, int const label);// prototype void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } } // extern "C" namespace BSP { // BSP functions ============================================================= void init(void) { // Configure the MPU to prevent NULL-pointer dereferencing // see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu // MPU->RBAR = 0x0U // base address (NULL) | MPU_RBAR_VALID_Msk // valid region | (MPU_RBAR_REGION_Msk & 7U); // region #7 MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region | (0x0U << MPU_RASR_AP_Pos) // no-access region | MPU_RASR_ENABLE_Msk; // region enable MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region | MPU_CTRL_ENABLE_Msk; // enable the MPU __ISB(); __DSB(); // enable GPIO port PA clock RCC->IOPENR |= (1U << 0U); // set all used GPIOA pins as push-pull output, no pull-up, pull-down GPIOA->MODER &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); GPIOA->MODER |= ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); GPIOA->OTYPER &= ~((1U << TST1_PIN) | (1U << TST2_PIN) | (1U << TST3_PIN) | (1U << TST4_PIN) | (1U << TST5_PIN) | (1U << TST6_PIN)); GPIOA->OSPEEDR &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); GPIOA->OSPEEDR |= ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); GPIOA->PUPDR &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); // enable GPIOC clock port for the Button B1 RCC->IOPENR |= (1U << 2U); // configure Button B1 pin on GPIOC as input, no pull-up, pull-down GPIOC->MODER &= ~(3U << 2U*B1_PIN); GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); } //............................................................................ void d1on(void) { GPIOA->BSRR = (1U << TST1_PIN); } void d1off(void) { GPIOA->BSRR = (1U << (TST1_PIN + 16U)); } //............................................................................ void d2on(void) { GPIOA->BSRR = (1U << TST2_PIN); } void d2off(void) { GPIOA->BSRR = (1U << (TST2_PIN + 16U)); } //............................................................................ void d3on(void) { GPIOA->BSRR = (1U << TST3_PIN); } void d3off(void) { GPIOA->BSRR = (1U << (TST3_PIN + 16U)); } //............................................................................ void d4on(void) { GPIOA->BSRR = (1U << TST4_PIN); } void d4off(void) { GPIOA->BSRR = (1U << (TST4_PIN + 16U)); } //............................................................................ void d5on(void) { GPIOA->BSRR = (1U << TST5_PIN); } void d5off(void) { GPIOA->BSRR = (1U << (TST5_PIN + 16U)); } //............................................................................ void d6on(void) { GPIOA->BSRR = (1U << TST6_PIN); } // LD4 void d6off(void) { GPIOA->BSRR = (1U << (TST6_PIN + 16U)); } //............................................................................ SST::Evt const *getWorkEvtBlinky1(uint8_t num) { // immutable work events for Blinky1 static App::BlinkyWorkEvt const workBlinky1[] = { { { App::BLINKY_WORK_SIG }, 40U, 5U }, { { App::BLINKY_WORK_SIG }, 30U, 7U } }; DBC_REQUIRE(500, num < ARRAY_NELEM(workBlinky1)); // num must be in range return &workBlinky1[num].super; } //............................................................................ SST::Evt const *getWorkEvtBlinky3(uint8_t num) { // immutable work events for Blinky3 static App::BlinkyWorkEvt const workBlinky3[] = { { { App::BLINKY_WORK_SIG }, 20U, 5U }, { { App::BLINKY_WORK_SIG }, 10U, 3U } }; DBC_REQUIRE(600, num < ARRAY_NELEM(workBlinky3)); // num must be in range return &workBlinky3[num].super; } } // namespace BSP // SST callbacks ============================================================= namespace SST { void onStart(void) { SystemCoreClockUpdate(); // set up the SysTick timer to fire at BSP::TICKS_PER_SEC rate SysTick_Config((SystemCoreClock / BSP::TICKS_PER_SEC) + 1U); // set priorities of ISRs used in the system NVIC_SetPriority(SysTick_IRQn, 0U); // ... } //............................................................................ void onIdleCond(void) { // NOTE: called with interrupts DISABLED BSP::d6on(); // turn LED2 on #ifdef NDEBUG // Put the CPU and peripherals to the low-power mode. // you might need to customize the clock management for your application, // see the datasheet for your particular Cortex-M MCU. // BSP::d6off(); // turn LED2 off __WFI(); // Wait-For-Interrupt BSP::d6on(); // turn LED2 on #endif BSP::d6off(); // turn LED2 off SST_PORT_INT_ENABLE(); // NOTE: enable interrupts for SS0 } } // namespace SST ================================================ FILE: sst0_cpp/examples/blinky_button/bsp_nucleo-h743zi.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST0/C++) Example for STM32 NUCLEO-H74cZI // // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // // Copyright (C) 2005 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface #include "stm32h743xx.h" // CMSIS-compliant header file for the MCU used #include // to exercise the FPU // add other drivers if necessary... // Local-scope defines ------------------------------------------------------- namespace { DBC_MODULE_NAME("bsp_nucleo-h743zi") // for DBC assertions in this module } // unnamed workspace // test pins on GPIO PB #define TST1_PIN 0U /* PB.0 LED1-Green */ #define TST2_PIN 14U /* PB.14 LED3-Red */ #define TST3_PIN 4U #define TST4_PIN 5U #define TST5_PIN 6U #define TST6_PIN 7U /* PB.7 LED2-Blue */ // buttons on GPIO PC #define B1_PIN 13U // ISRs used in the application ============================================== extern "C" { void SysTick_Handler(void) { // system clock tick ISR BSP::d1on(); SST::TimeEvt::tick(); // get state of the user button // Perform the debouncing of buttons. The algorithm for debouncing // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle // and Michael Barr, page 71. // static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = GPIOC->IDR; // read GPIO PortC uint32_t tmp = buttons.depressed; // save the debounced depressed buttons.depressed |= (buttons.previous & current); // set depressed buttons.depressed &= (buttons.previous | current); // clear released buttons.previous = current; // update the history tmp ^= buttons.depressed; // changed debounced depressed if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? if ((buttons.depressed & (1U << B1_PIN)) != 0U) { // depressed? // immutable button-press event static App::ButtonWorkEvt const pressEvt = { { App::BUTTON_PRESSED_SIG }, 60U }; // immutable forward-press event static App::ButtonWorkEvt const fPressEvt = { { App::FORWARD_PRESSED_SIG }, 60U }; App::AO_Button2a->post(&fPressEvt.super); App::AO_Button2a->post(&pressEvt.super); } else { // B1 is released // immutable button-release event static App::ButtonWorkEvt const releaseEvt = { { App::BUTTON_RELEASED_SIG }, 80U }; // immutable forward-release event static App::ButtonWorkEvt const fReleaseEvt = { { App::FORWARD_RELEASED_SIG }, 80U }; App::AO_Button2a->post(&fReleaseEvt.super); App::AO_Button2a->post(&releaseEvt.super); } } BSP::d1off(); } // Assertion handler ========================================================= void DBC_fault_handler(char const * const module, int const label) { // // NOTE: add here your application-specific error handling // (void)module; (void)label; // set PRIMASK to disable interrupts and stop SST right here __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { // keep blinking LED2 BSP::d6on(); // turn LED2 on uint32_t volatile ctr; for (ctr = 1000000U; ctr > 0U; --ctr) { } BSP::d6off(); // turn LED2 off for (ctr = 1000000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } //............................................................................ void assert_failed(char const * const module, int const label);// prototype void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } } // extern "C" namespace BSP { // BSP functions ============================================================= void init(void) { // Configure the MPU to prevent NULL-pointer dereferencing // see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu // MPU->RBAR = 0x0U // base address (NULL) | MPU_RBAR_VALID_Msk // valid region | (MPU_RBAR_REGION_Msk & 7U); // region #7 MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region | (0x0U << MPU_RASR_AP_Pos) // no-access region | MPU_RASR_ENABLE_Msk; // region enable MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region | MPU_CTRL_ENABLE_Msk; // enable the MPU __ISB(); __DSB(); SCB_EnableICache(); // Enable I-Cache SCB_EnableDCache(); // Enable D-Cache // enable GPIOB port clock for LEds and test pins RCC->AHB4ENR |= RCC_AHB4ENR_GPIOBEN; // set all used GPIOB pins as push-pull output, no pull-up, pull-down GPIOB->MODER &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); GPIOB->MODER |= ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); GPIOB->OTYPER &= ~((1U << TST1_PIN) | (1U << TST2_PIN) | (1U << TST3_PIN) | (1U << TST4_PIN) | (1U << TST5_PIN) | (1U << TST6_PIN)); GPIOB->PUPDR &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); // enable GPIOC clock port for the Button B1 RCC->AHB4ENR |= RCC_AHB4ENR_GPIOCEN; // configure Button B1 pin on GPIOC as input, no pull-up, pull-down GPIOC->MODER &= ~(3U << 2U*B1_PIN); GPIOC->PUPDR &= ~(GPIO_PUPDR_PUPD0 << 2U*B1_PIN); GPIOC->PUPDR |= (2U << 2U*B1_PIN); } //............................................................................ static void exerciseFPU(double x) { // exercise the double-precision FPU by calculating the identity: // sin(x)^2 + cos(x)^2 == 1.0 for any x // double tmp = pow(sin(x), 2.0) + pow(cos(x), 2.0); DBC_ENSURE(200, ((1.0 - 1e-4) < tmp) && (tmp < (1.0 + 1e-4))); } //............................................................................ void d1on(void) { // LED1-Green GPIOB->BSRR = (1U << TST1_PIN); // don't use the FPU in the ISR } void d1off(void) { GPIOB->BSRR = (1U << (TST1_PIN + 16U)); } //............................................................................ void d2on(void) { // LED3-Red GPIOB->BSRR = (1U << TST2_PIN); exerciseFPU(-1.2345); } void d2off(void) { GPIOB->BSRR = (1U << (TST2_PIN + 16U)); } //............................................................................ void d3on(void) { GPIOB->BSRR = (1U << TST3_PIN); exerciseFPU(-12.345); } void d3off(void) { GPIOB->BSRR = (1U << (TST3_PIN + 16U)); } //............................................................................ void d4on(void) { GPIOB->BSRR = (1U << TST4_PIN); exerciseFPU(3.456); } void d4off(void) { GPIOB->BSRR = (1U << (TST4_PIN + 16U)); } //............................................................................ void d5on(void) { GPIOB->BSRR = (1U << TST5_PIN); exerciseFPU(4.567); } void d5off(void) { GPIOB->BSRR = (1U << (TST5_PIN + 16U)); } //............................................................................ void d6on(void) { // LED2-Blue GPIOB->BSRR = (1U << TST6_PIN); exerciseFPU(1.2345); } void d6off(void) { GPIOB->BSRR = (1U << (TST6_PIN + 16U)); } //............................................................................ SST::Evt const *getWorkEvtBlinky1(uint8_t num) { // immutable work events for Blinky1 static App::BlinkyWorkEvt const workBlinky1[] = { { { App::BLINKY_WORK_SIG }, 40U, 5U }, { { App::BLINKY_WORK_SIG }, 30U, 7U } }; DBC_REQUIRE(500, num < ARRAY_NELEM(workBlinky1)); // num must be in range return &workBlinky1[num].super; } //............................................................................ SST::Evt const *getWorkEvtBlinky3(uint8_t num) { // immutable work events for Blinky3 static App::BlinkyWorkEvt const workBlinky3[] = { { { App::BLINKY_WORK_SIG }, 20U, 5U }, { { App::BLINKY_WORK_SIG }, 10U, 3U } }; DBC_REQUIRE(600, num < ARRAY_NELEM(workBlinky3)); // num must be in range return &workBlinky3[num].super; } } // namespace BSP // SST callbacks ============================================================= namespace SST { void onStart(void) { SystemCoreClockUpdate(); // set up the SysTick timer to fire at BSP::TICKS_PER_SEC rate SysTick_Config((SystemCoreClock / BSP::TICKS_PER_SEC) + 1U); // set priorities of ISRs used in the system NVIC_SetPriority(SysTick_IRQn, 0U); // ... } //............................................................................ void onIdleCond(void) { // NOTE: called with interrupts DISABLED BSP::d6on(); // turn LED2 on #ifdef NDEBUG // Put the CPU and peripherals to the low-power mode. // you might need to customize the clock management for your application, // see the datasheet for your particular Cortex-M MCU. // BSP::d6off(); // turn LED2 off __WFI(); // Wait-For-Interrupt BSP::d6on(); // turn LED2 on #endif BSP::d6off(); // turn LED2 off SST_PORT_INT_ENABLE(); // NOTE: enable interrupts for SS0 } } // namespace SST ================================================ FILE: sst0_cpp/examples/blinky_button/bsp_nucleo-l053r8.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST0/C++) Example for STM32 NUCLEO-L053R8 // // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // // Copyright (C) 2005 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface #include "stm32l0xx.h" // CMSIS-compliant header file for the MCU used // add other drivers if necessary... // Local-scope defines ------------------------------------------------------- namespace { DBC_MODULE_NAME("bsp_nucleo-l053r8") // for DBC assertions in this module } // unnamed workspace // test pins on GPIO PA #define TST1_PIN 7U #define TST2_PIN 6U #define TST3_PIN 4U #define TST4_PIN 1U #define TST5_PIN 0U #define TST6_PIN 5U /* LED LD2-Green */ // buttons on GPIO PC #define B1_PIN 13U // ISRs used in the application ============================================== extern "C" { void SysTick_Handler(void); // prototype void SysTick_Handler(void) { // system clock tick ISR BSP::d1on(); SST::TimeEvt::tick(); // get state of the user button // Perform the debouncing of buttons. The algorithm for debouncing // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle // and Michael Barr, page 71. // static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = ~GPIOC->IDR; // read GPIO PortC uint32_t tmp = buttons.depressed; // save the debounced depressed buttons.depressed |= (buttons.previous & current); // set depressed buttons.depressed &= (buttons.previous | current); // clear released buttons.previous = current; // update the history tmp ^= buttons.depressed; // changed debounced depressed if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? if ((buttons.depressed & (1U << B1_PIN)) != 0U) { // depressed? // immutable button-press event static App::ButtonWorkEvt const pressEvt = { { App::BUTTON_PRESSED_SIG }, 60U }; // immutable forward-press event static App::ButtonWorkEvt const fPressEvt = { { App::FORWARD_PRESSED_SIG }, 60U }; App::AO_Button2a->post(&fPressEvt.super); App::AO_Button2a->post(&pressEvt.super); } else { // B1 is released // immutable button-release event static App::ButtonWorkEvt const releaseEvt = { { App::BUTTON_RELEASED_SIG }, 80U }; // immutable forward-release event static App::ButtonWorkEvt const fReleaseEvt = { { App::FORWARD_RELEASED_SIG }, 80U }; App::AO_Button2a->post(&fReleaseEvt.super); App::AO_Button2a->post(&releaseEvt.super); } } BSP::d1off(); } // Assertion handler ========================================================= void DBC_fault_handler(char const * const module, int const label) { // // NOTE: add here your application-specific error handling // (void)module; (void)label; // set PRIMASK to disable interrupts and stop SST right here __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { // keep blinking LED2 BSP::d6on(); // turn LED2 on uint32_t volatile ctr; for (ctr = 10000U; ctr > 0U; --ctr) { } BSP::d6off(); // turn LED2 off for (ctr = 10000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } //............................................................................ void assert_failed(char const * const module, int const label);// prototype void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } } // extern "C" namespace BSP { // BSP functions ============================================================= void init(void) { // Configure the MPU to prevent NULL-pointer dereferencing // see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu // MPU->RBAR = 0x0U // base address (NULL) | MPU_RBAR_VALID_Msk // valid region | (MPU_RBAR_REGION_Msk & 7U); // region #7 MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region | (0x0U << MPU_RASR_AP_Pos) // no-access region | MPU_RASR_ENABLE_Msk; // region enable MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region | MPU_CTRL_ENABLE_Msk; // enable the MPU __ISB(); __DSB(); // enable GPIO port PA clock RCC->IOPENR |= (1U << 0U); // set all used GPIOA pins as push-pull output, no pull-up, pull-down GPIOA->MODER &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); GPIOA->MODER |= ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); GPIOA->OTYPER &= ~((1U << TST1_PIN) | (1U << TST2_PIN) | (1U << TST3_PIN) | (1U << TST4_PIN) | (1U << TST5_PIN) | (1U << TST6_PIN)); GPIOA->PUPDR &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); // enable GPIOC clock port for the Button B1 RCC->IOPENR |= (1U << 2U); // configure Button B1 pin on GPIOC as input, no pull-up, pull-down GPIOC->MODER &= ~(3U << 2U*B1_PIN); GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); } //............................................................................ void d1on(void) { GPIOA->BSRR = (1U << TST1_PIN); } void d1off(void) { GPIOA->BSRR = (1U << (TST1_PIN + 16U)); } //............................................................................ void d2on(void) { GPIOA->BSRR = (1U << TST2_PIN); } void d2off(void) { GPIOA->BSRR = (1U << (TST2_PIN + 16U)); } //............................................................................ void d3on(void) { GPIOA->BSRR = (1U << TST3_PIN); } void d3off(void) { GPIOA->BSRR = (1U << (TST3_PIN + 16U)); } //............................................................................ void d4on(void) { GPIOA->BSRR = (1U << TST4_PIN); } void d4off(void) { GPIOA->BSRR = (1U << (TST4_PIN + 16U)); } //............................................................................ void d5on(void) { GPIOA->BSRR = (1U << TST5_PIN); } void d5off(void) { GPIOA->BSRR = (1U << (TST5_PIN + 16U)); } //............................................................................ void d6on(void) { GPIOA->BSRR = (1U << TST6_PIN); } // LED2 void d6off(void) { GPIOA->BSRR = (1U << (TST6_PIN + 16U)); } //............................................................................ SST::Evt const *getWorkEvtBlinky1(uint8_t num) { // immutable work events for Blinky1 static App::BlinkyWorkEvt const workBlinky1[] = { { { App::BLINKY_WORK_SIG }, 40U, 5U }, { { App::BLINKY_WORK_SIG }, 30U, 7U } }; DBC_REQUIRE(500, num < ARRAY_NELEM(workBlinky1)); // num must be in range return &workBlinky1[num].super; } //............................................................................ SST::Evt const *getWorkEvtBlinky3(uint8_t num) { // immutable work events for Blinky3 static App::BlinkyWorkEvt const workBlinky3[] = { { { App::BLINKY_WORK_SIG }, 20U, 5U }, { { App::BLINKY_WORK_SIG }, 10U, 3U } }; DBC_REQUIRE(600, num < ARRAY_NELEM(workBlinky3)); // num must be in range return &workBlinky3[num].super; } } // namespace BSP // SST callbacks ============================================================= namespace SST { void onStart(void) { SystemCoreClockUpdate(); // set up the SysTick timer to fire at BSP::TICKS_PER_SEC rate SysTick_Config((SystemCoreClock / BSP::TICKS_PER_SEC) + 1U); // set priorities of ISRs used in the system NVIC_SetPriority(SysTick_IRQn, 0U); // ... } //............................................................................ void onIdleCond(void) { // NOTE: called with interrupts DISABLED BSP::d6on(); // turn LED2 on #ifdef NDEBUG // Put the CPU and peripherals to the low-power mode. // you might need to customize the clock management for your application, // see the datasheet for your particular Cortex-M MCU. // BSP::d6off(); // turn LED2 off __WFI(); // Wait-For-Interrupt BSP::d6on(); // turn LED2 on #endif BSP::d6off(); // turn LED2 off SST_PORT_INT_ENABLE(); // NOTE: enable interrupts for SS0 } } // namespace SST ================================================ FILE: sst0_cpp/examples/blinky_button/button2a.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface namespace { DBC_MODULE_NAME("button2a") // for DBC assertions in this module } // unnamed namespace namespace App { //............................................................................ class Button2a : public SST::Task { // add internal variables for this AO... public: static Button2a inst; void init(SST::Evt const * const ie) override; void dispatch(SST::Evt const * const e) override; }; //............................................................................ Button2a Button2a::inst; // the Button2a instance SST::Task * const AO_Button2a = &Button2a::inst; // opaque AO pointer //............................................................................ void Button2a::init(SST::Evt const * const /*ie*/) { } //............................................................................ void Button2a::dispatch(SST::Evt const * const e) { switch (e->sig) { case BUTTON_PRESSED_SIG: { BSP::d4on(); // Button2a --> Blinky1 AO_Blinky1->post(BSP::getWorkEvtBlinky1(1U)); BSP::d4off(); for (std::uint16_t i = SST::evt_downcast(e)->toggles; i > 0U; --i) { BSP::d4on(); BSP::d4off(); } break; } case FORWARD_PRESSED_SIG: { BSP::d4on(); // immutable event can be forwarded to another Task AO_Button2b->post(e); // Button2a --> Button2b BSP::d4off(); break; } case BUTTON_RELEASED_SIG: { static BlinkyWorkEvt const bw2evt = { { BLINKY_WORK_SIG }, 30U, 7U }; AO_Blinky1->post(&bw2evt.super); // Button2b --> Blinky1 for (uint16_t i = SST::evt_downcast(e)->toggles; i > 0U; --i) { BSP::d4on(); BSP::d4off(); } break; } case FORWARD_RELEASED_SIG: { BSP::d4on(); // immutable event can be forwarded to another Task AO_Button2b->post(e); // Button2a --> Button2b BSP::d4off(); break; } default: { DBC_ERROR(500); // unexpected event break; } } } } // namespace App ================================================ FILE: sst0_cpp/examples/blinky_button/button2b.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface namespace { DBC_MODULE_NAME("button2b") // for DBC assertions in this module } // unnamed namespace namespace App { //............................................................................ class Button2b : public SST::Task { // add internal variables for this AO... public: static Button2b inst; void init(SST::Evt const * const ie) override; void dispatch(SST::Evt const * const e) override; }; //............................................................................ Button2b Button2b::inst; // the Button2b instance SST::Task * const AO_Button2b = &Button2b::inst; // opaque AO pointer //............................................................................ void Button2b::init(SST::Evt const * const /*ie*/) { } //............................................................................ void Button2b::dispatch(SST::Evt const * const e) { switch (e->sig) { case FORWARD_PRESSED_SIG: { BSP::d3on(); // Button2b --> Blinky3 AO_Blinky3->post(BSP::getWorkEvtBlinky3(1U)); BSP::d3off(); for (std::uint16_t i = SST::evt_downcast(e)->toggles; i > 0U; --i) { BSP::d3on(); BSP::d3off(); } break; } case FORWARD_RELEASED_SIG: { BSP::d3on(); // Button2b --> Blinky3 AO_Blinky3->post(BSP::getWorkEvtBlinky3(0U)); BSP::d3off(); for (uint16_t i = SST::evt_downcast(e)->toggles; i > 0U; --i) { BSP::d3on(); BSP::d3off(); } break; } default: { DBC_ERROR(500); /* unexpected event */ break; } } } } // namespace App ================================================ FILE: sst0_cpp/examples/blinky_button/gnu/ek-tm4c123gxl.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST0/C++) on TM4C123GXL, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-01-25 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f ek-tm4c123gxl.mak # make -f ek-tm4c123gxl.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky_button TARGET := ek-tm4c123gxl #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ system_TM4C123GH6PM.c \ startup_TM4C123GH6PM.c # C++ source files CPP_SRCS := \ sst0.cpp \ main.cpp \ blinky1.cpp \ blinky3.cpp \ button2a.cpp \ button2b.cpp \ bsp_ek-tm4c123gxl.cpp LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := -DTARGET_IS_TM4C123_RB1 # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m4 ARM_FPU := -mfpu=vfp FLOAT_ABI := -mfloat-abi=softfp #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-g++ BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst0_cpp/examples/blinky_button/gnu/flash_ek-tm4c123gxl.bat ================================================ ::============================================================================ :: Batch file to program the flash of EK-TM4C123GXL :: :: NOTE: requires the LMFlash programmer (included in QTools for Windows) :: @echo off setlocal @echo Load a given binary file to the flash of EK-TM4C123GXL @echo usage: flash binary-file @echo example: flash dbg\blinky-qk.bin ::---------------------------------------------------------------------------- :: NOTE: The following symbol LMFLASH assumes that LMFlash.exe can :: be found on the PATH. You might need to adjust this symbol to the :: location of the LMFlash utility on your machine :: set LMFLASH=LMFlash.exe if ["%~1"]==[""] ( @echo The binary file missing @goto end ) if not exist %~s1 ( @echo The binary file '%1' does not exist @goto end ) %LMFLASH% -q ek-tm4c123gxl -e -v -r %1 :end endlocal ================================================ FILE: sst0_cpp/examples/blinky_button/gnu/nucleo-c031c6.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST0/C++) on NUCLEO-C031C6, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-02-01 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f nucleo-c031c6.mak # make -f nucleo-c031c6.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky_button TARGET := nucleo-c031c6 #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ system_stm32c0xx.c \ startup_stm32c031xx.c # C++ source files CPP_SRCS := \ sst0.cpp \ main.cpp \ blinky1.cpp \ blinky3.cpp \ button2a.cpp \ button2b.cpp \ bsp_nucleo-c031c6.cpp LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := -DSTM32C031xx # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m0plus ARM_FPU := FLOAT_ABI := #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-g++ BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst0_cpp/examples/blinky_button/gnu/nucleo-h743zi.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST/C++) on NUCLEO-H743ZI, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-01-22 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f nucleo-h743zi.mak # make -f nucleo-h743zi.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky_button TARGET := nucleo-h743zi #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ startup_stm32h743xx.c \ system_stm32h7xx.c # C++ source files CPP_SRCS := \ sst0.cpp \ main.cpp \ blinky1.cpp \ blinky3.cpp \ button2a.cpp \ button2b.cpp \ bsp_nucleo-h743zi.cpp LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := -DSTM32H743xx # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m7 ARM_FPU := -mfpu=fpv5-d16 FLOAT_ABI := -mfloat-abi=softfp #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-g++ BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst0_cpp/examples/blinky_button/gnu/nucleo-l053r8.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST/C++) on NUCLEO-L053R8, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-01-22 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f nucleo-l053r8.mak # make -f nucleo-l053r8.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky_button TARGET := nucleo-l053r8 #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ system_stm32l0xx.c \ startup_stm32l053xx.c # C++ source files CPP_SRCS := \ sst0.cpp \ main.cpp \ blinky1.cpp \ blinky3.cpp \ button2a.cpp \ button2b.cpp \ bsp_nucleo-l053r8.cpp LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m0plus ARM_FPU := FLOAT_ABI := #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-g++ BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst0_cpp/examples/blinky_button/iar/ek-tm4c123gxl.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst0_cpp/examples/blinky_button/iar/ek-tm4c123gxl.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Application $PROJ_DIR$\..\blinky1.cpp $PROJ_DIR$\..\blinky3.cpp $PROJ_DIR$\..\bsp.hpp $PROJ_DIR$\..\bsp_ek-tm4c123gxl.cpp $PROJ_DIR$\..\button2a.cpp $PROJ_DIR$\..\button2b.cpp $PROJ_DIR$\..\main.cpp ek-tm4c123gxl $PROJ_DIR$\..\..\..\..\3rd_party\ek-tm4c123gxl\iar\startup_TM4C123GH6PM.s $PROJ_DIR$\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c $PROJ_DIR$\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h sst $PROJ_DIR$\..\..\..\src\sst0.cpp sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.hpp ================================================ FILE: sst0_cpp/examples/blinky_button/iar/ek-tm4c123gxl.eww ================================================ $WS_DIR$\ek-tm4c123gxl.ewp ================================================ FILE: sst0_cpp/examples/blinky_button/iar/nucleo-c031c6.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst0_cpp/examples/blinky_button/iar/nucleo-c031c6.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Debug Application $PROJ_DIR$\..\blinky1.cpp $PROJ_DIR$\..\blinky3.cpp $PROJ_DIR$\..\blinky_button.hpp $PROJ_DIR$\..\bsp.hpp $PROJ_DIR$\..\bsp_nucleo-c031c6.cpp $PROJ_DIR$\..\button2a.cpp $PROJ_DIR$\..\button2b.cpp $PROJ_DIR$\..\main.cpp nucleo-c031c6 $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-c031c6\iar\startup_stm32c031xx.s $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.h sst $PROJ_DIR$\..\..\..\src\sst0.cpp sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.hpp ================================================ FILE: sst0_cpp/examples/blinky_button/iar/nucleo-c031c6.eww ================================================ $WS_DIR$\nucleo-c031c6.ewp ================================================ FILE: sst0_cpp/examples/blinky_button/iar/nucleo-h743zi.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst0_cpp/examples/blinky_button/iar/nucleo-h743zi.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Debug Application $PROJ_DIR$\..\blinky1.cpp $PROJ_DIR$\..\blinky3.cpp $PROJ_DIR$\..\blinky_button.hpp $PROJ_DIR$\..\bsp.hpp $PROJ_DIR$\..\bsp_nucleo-h743zi.cpp $PROJ_DIR$\..\button2a.cpp $PROJ_DIR$\..\button2b.cpp $PROJ_DIR$\..\main.cpp nucleo-h743zi $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-h743zi\iar\startup_stm32h743xx.s $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-h743zi\stm32h743xx.h $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-h743zi\system_stm32h7xx.c sst $PROJ_DIR$\..\..\..\src\sst0.cpp sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.hpp ================================================ FILE: sst0_cpp/examples/blinky_button/iar/nucleo-h743zi.eww ================================================ $WS_DIR$\nucleo-h743zi.ewp ================================================ FILE: sst0_cpp/examples/blinky_button/iar/nucleo-l053r8.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst0_cpp/examples/blinky_button/iar/nucleo-l053r8.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Debug Application $PROJ_DIR$\..\blinky1.cpp $PROJ_DIR$\..\blinky3.cpp $PROJ_DIR$\..\blinky_button.hpp $PROJ_DIR$\..\bsp.hpp $PROJ_DIR$\..\bsp_nucleo-l053r8.cpp $PROJ_DIR$\..\button2a.cpp $PROJ_DIR$\..\button2b.cpp $PROJ_DIR$\..\main.cpp nucleo-l053r8 $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\iar\startup_stm32l053xx.s $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c sst $PROJ_DIR$\..\..\..\src\sst0.cpp sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.hpp ================================================ FILE: sst0_cpp/examples/blinky_button/iar/nucleo-l053r8.eww ================================================ $WS_DIR$\nucleo-l053r8.ewp ================================================ FILE: sst0_cpp/examples/blinky_button/main.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST0/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface //............................................................................ int main() { SST::init(); // initialize the SST kernel BSP::init(); // initialize the Board Support Package // instantiate and start all SST tasks... static SST::Evt const *blinky1QSto[10]; // Event queue storage App::AO_Blinky1->start( 1U, // SST-priority blinky1QSto, // storage for the AO's queue ARRAY_NELEM(blinky1QSto), // queue length BSP::getWorkEvtBlinky1(0U)); // initialization event static SST::Evt const *button2aQSto[8]; // Event queue storage App::AO_Button2a->start( 2U, // SST-priority button2aQSto, // storage for the AO's queue ARRAY_NELEM(button2aQSto), // queue length nullptr); // initialization event static SST::Evt const *button2bQSto[6]; // Event queue storage App::AO_Button2b->start( 3U, // SST-priority button2bQSto, // storage for the AO's queue ARRAY_NELEM(button2bQSto), // queue length nullptr); // initialization event static SST::Evt const *blinky3QSto[4]; // Event queue storage App::AO_Blinky3->start( 4U, // SST-priority blinky3QSto, // storage for the AO's queue ARRAY_NELEM(blinky3QSto), // queue length BSP::getWorkEvtBlinky3(0U)); // initialization event return SST::Task::run(); // run the SST tasks // NOTE: in embedded systems SST::Task::run() should not return } ================================================ FILE: sst0_cpp/ports/arm-cm/sst_port.hpp ================================================ //============================================================================ // Super-Simple Tasker (SST0/C++) port // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #ifndef SST_PORT_HPP_ #define SST_PORT_HPP_ #define SST_PORT_MAX_TASK 32U // additional SST-PORT task attributes for ARM Cortex-M #define SST_PORT_TASK_ATTR \ SST::TaskPrio m_prio; // SST-PORT disabling/enabling interrupts #define SST_PORT_INT_DISABLE() __asm volatile ("cpsid i") #define SST_PORT_INT_ENABLE() __asm volatile ("cpsie i") // SST-PORT critical section #define SST_PORT_CRIT_STAT #define SST_PORT_CRIT_ENTRY() SST_PORT_INT_DISABLE() #define SST_PORT_CRIT_EXIT() SST_PORT_INT_ENABLE() namespace SST { using ReadySet = std::uint32_t; //! SST lock key using LockKey = std::uint32_t; // special idle callback to handle the "idle condition" in SST0 void onIdleCond(void); } #if (__ARM_ARCH == 6) // ARMv6-M? // SST_LOG2() implementation for ARMv6-M (no CLZ instruction) inline std::uint_fast8_t SST_LOG2(std::uint32_t x) { static std::uint8_t const log2LUT[16] = { 0U, 1U, 2U, 2U, 3U, 3U, 3U, 3U, 4U, 4U, 4U, 4U, 4U, 4U, 4U, 4U }; std::uint_fast8_t n = 0U; SST::ReadySet tmp; #if (SST_PORT_MAX_TASK > 16U) tmp = static_cast(x >> 16U); if (tmp != 0U) { n += 16U; x = tmp; } #endif #if (SST_PORT_MAX_TASK > 8U) tmp = (x >> 8U); if (tmp != 0U) { n += 8U; x = tmp; } #endif tmp = (x >> 4U); if (tmp != 0U) { n += 4U; x = tmp; } return n + log2LUT[x]; } #else // ARMv7-M+ have CLZ instruction for fast LOG2 computations // ARMv7-M+ have CLZ instruction for fast LOG2 computations #if defined __ARMCC_VERSION #define SST_LOG2(x_) \ (static_cast(32U - __builtin_clz((unsigned)(x_)))) #elif defined __GNUC__ #define SST_LOG2(x_) \ (static_cast(32U - __builtin_clz((unsigned)(x_)))) #elif defined __ICCARM__ #include #define SST_LOG2(x_) \ (static_cast(32U - __CLZ((unsigned long)(x_)))) #endif /* compiler type */ #endif #endif // SST_PORT_HPP_ ================================================ FILE: sst0_cpp/src/sst0.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST0/C++) port // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // Super-Simple Tasker (SST) in C++ #include "dbc_assert.h" // Design By Contract (DBC) assertions //............................................................................ namespace { // unnamed namespace DBC_MODULE_NAME("sst0") // for DBC assertions in this module static SST::ReadySet task_readySet; // array of all SST task pointers in the system static SST::Task *task_registry[SST_PORT_MAX_TASK + 1U]; } // unnamed namespace namespace SST { // SST kernel facilities ----------------------------------------------------- void init(void) { } //............................................................................ int Task::run(void) { // static onStart(); // configure and start the interrupts SST_PORT_INT_DISABLE(); for (;;) { // event loop of the SST0 kernel if (task_readySet != 0U) { // any SST tasks ready to run? std::uint_fast8_t const p = SST_LOG2(task_readySet); Task * const task = task_registry[p]; SST_PORT_INT_ENABLE(); // the task must have some events in the queue DBC_ASSERT(100, task->m_nUsed > 0U); // get the event out of the queue // NOTE: no critical section because task->m_tail is accessed // only from this task // Evt const *e = task->m_qBuf[task->m_tail]; if (task->m_tail == 0U) { /* need to wrap the tail? */ task->m_tail = task->m_end; /* wrap around */ } else { --task->m_tail; } SST_PORT_INT_DISABLE(); if ((--task->m_nUsed) == 0U) { /* no more events in the queue? */ task_readySet &= ~(1U << (p - 1U)); } SST_PORT_INT_ENABLE(); // dispatch the received event to this task task->dispatch(e); // virtual call // TBD: implement event recycling } else { // no SST tasks are ready to run --> idle // SST::onIdleCond() must be called with interrupts DISABLED // because the determination of the idle condition (all event // queues empty) can change at any time by an interrupt posting // events to a queue. // // NOTE: SST::onIdleCond() MUST enable interrupts internally, // ideally at the same time as putting the CPU into a power- // saving mode. // onIdleCond(); SST_PORT_INT_DISABLE(); /* disable before looping back */ } } #ifdef __GNUC__ // GNU compiler? */ return 0; #endif } // SST Task facilities ------------------------------------------------------- void Task::start( TaskPrio prio, Evt const **qBuf, QCtr qLen, Evt const * const ie) { //! @pre // - the priority must be in range // - the queue storage must be provided // - the queue length must not be zero // - the priority must not be in use // DBC_REQUIRE(200, (0U < prio) && (prio <= SST_PORT_MAX_TASK) && (qBuf != nullptr) && (qLen > 0U) && (task_registry[prio] == nullptr)); m_prio = prio; m_qBuf = qBuf; m_end = qLen - 1U; m_head = 0U; m_tail = 0U; m_nUsed = 0U; task_registry[prio] = this; // initialize this task with the initialization event init(ie); // virtual call // TBD: implement event recycling } //............................................................................ void Task::post(Evt const * const e) noexcept { //! @pre the queue must be sized adequately and cannot overflow DBC_REQUIRE(300, m_nUsed <= m_end); SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); m_qBuf[m_head] = e; // insert event into the queue // need to wrap the head? if (m_head == 0U) { m_head = m_end; // wrap around } else { --m_head; } ++m_nUsed; task_readySet |= (1U << (m_prio - 1U)); SST_PORT_CRIT_EXIT(); } //---------------------------------------------------------------------------- static TimeEvt *timeEvt_head = nullptr; //............................................................................ TimeEvt::TimeEvt(Signal sig, Task *task) { this->sig = sig; m_task = task; m_ctr = 0U; m_interval = 0U; // insert this time event into the linked-list m_next = timeEvt_head; timeEvt_head = this; } //............................................................................ void TimeEvt::arm(TCtr ctr, TCtr interval) { SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); m_ctr = ctr; m_interval = interval; SST_PORT_CRIT_EXIT(); } //............................................................................ bool TimeEvt::disarm(void) { SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); bool status = (m_ctr != 0U); m_ctr = 0U; m_interval = 0U; SST_PORT_CRIT_EXIT(); return status; } //............................................................................ void TimeEvt::tick(void) { for (TimeEvt *t = timeEvt_head; t != nullptr; t = t->m_next) { SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); if (t->m_ctr == 0U) { // disarmed? (most frequent case) SST_PORT_CRIT_EXIT(); } else if (t->m_ctr == 1U) { // expiring? t->m_ctr = t->m_interval; SST_PORT_CRIT_EXIT(); t->m_task->post(t); } else { // timing out --t->m_ctr; SST_PORT_CRIT_EXIT(); } } } } // namespace SST ================================================ FILE: sst_c/README.txt ================================================ This directory contains the SST implementation in C roughly corresponding to the BCC2 conformance class in the OSEK/VDX Operating System specification. This SST implementation is referred to as "SST/C". - "basic tasks" (non-blocking) - preemptive scheduling - multiple tasks per prioriy level - multiple "activations" per task (event queues) ================================================ FILE: sst_c/examples/README.txt ================================================ This directory contains examples for the preemptive SST/C kernel. ================================================ FILE: sst_c/examples/blinky/armclang/nucleo-l053r8.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 nucleo-l053r8 0x4 ARM-ADS 12000000 1 1 0 1 0 1 65535 0 0 0 79 66 8 .\build_nucleo-l053r8\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 UL2CM3 UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM)) 0 ST-LINKIII-KEIL_SWO -U066CFF484951775087074312 -O8431 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P2 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC800 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=1702,853,2113,1355,0)(1007=2082,245,2289,466,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS 1 2 0xE000E400 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 10000000 Application 1 0 0 0 1 1 5 0 0 0 ..\blinky.h blinky.h 0 0 1 2 1 0 0 0 ..\blinky.c blinky.c 0 0 1 3 5 0 0 0 ..\bsp.h bsp.h 0 0 1 4 1 0 0 0 ..\bsp_nucleo-l053r8.c bsp_nucleo-l053r8.c 0 0 1 5 1 0 0 0 ..\main.c main.c 0 0 nucleo-l053r8 1 0 0 0 2 6 2 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s startup_stm32l053xx.s 0 0 2 7 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l0xx.h 0 0 2 8 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h stm32l053xx.h 0 0 2 9 1 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c system_stm32l0xx.c 0 0 sst 1 0 0 0 3 10 1 0 0 0 ..\..\..\src\sst.c sst.c 0 0 sst_port 1 0 0 0 4 11 1 0 0 0 ..\..\..\ports\arm-cm\sst_port.c sst_port.c 0 0 4 12 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.h sst_port.h 0 0
================================================ FILE: sst_c/examples/blinky/armclang/nucleo-l053r8.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
nucleo-l053r8 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32L053R8Tx STMicroelectronics Keil.STM32L0xx_DFP.2.2.0 http://www.keil.com/pack/ IRAM(0x20000000,0x00002000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$Flash\STM32L0xx_64.FLM)) 0 $$Device:STM32L053R8Tx$Device\Include\stm32l0xx.h $$Device:STM32L053R8Tx$SVD\STM32L053x.svd 0 0 0 0 0 0 1 .\build_nucleo-l053r8\ blinky_button 1 0 0 1 1 .\build_nucleo-l053r8\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-l053r8\blinky_button.bin .\build_nucleo-l053r8\blinky_button.axf 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP DARMCM1.DLL -pCM0+ SARMCM3.DLL TARMCM1.DLL -pCM0+ 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M0+" 0 0 0 1 1 0 0 0 0 0 0 0 8 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 1 0x8000000 0x10000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x10000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 0 0x0 0x0 0 0 0 0 1 0 0 0 0 0 4 0 1 0 0 0 3 3 0 0 0 0 0 -Wno-padded .;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-l053r8 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Application blinky.h 5 ..\blinky.h blinky.c 1 ..\blinky.c bsp.h 5 ..\bsp.h bsp_nucleo-l053r8.c 1 ..\bsp_nucleo-l053r8.c main.c 1 ..\main.c nucleo-l053r8 startup_stm32l053xx.s 2 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s stm32l0xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l053xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h system_stm32l0xx.c 1 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c sst sst.c 1 ..\..\..\src\sst.c sst_port sst_port.c 1 ..\..\..\ports\arm-cm\sst_port.c sst_port.h 5 ..\..\..\ports\arm-cm\sst_port.h nucleo-l053r8 1
================================================ FILE: sst_c/examples/blinky/blinky.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky.h" /* application shared interface */ DBC_MODULE_NAME("blinky") /* for DBC assertions in this module */ /* Blinky event-driven task ------------------------------------------------*/ typedef struct { SST_Task super; /* inherit SST_Task */ SST_TimeEvt te1; SST_TimeEvt te2; } Blinky; static void Blinky_ctor(Blinky * const me); static void Blinky_init(Blinky * const me, SST_Evt const * const ie); static void Blinky_dispatch(Blinky * const me, SST_Evt const * const e); /*..........................................................................*/ static Blinky Blinky_inst; /* the Blinky instance */ SST_Task * const AO_Blinky = &Blinky_inst.super; /* opaque AO pointer */ /*..........................................................................*/ void Blinky_instantiate(void) { Blinky_ctor(&Blinky_inst); } /*..........................................................................*/ void Blinky_ctor(Blinky * const me) { SST_Task_ctor( &me->super, (SST_Handler)&Blinky_init, (SST_Handler)&Blinky_dispatch); SST_TimeEvt_ctor(&me->te1, TIMEOUT1_SIG, &me->super); SST_TimeEvt_ctor(&me->te2, TIMEOUT2_SIG, &me->super); } /* macro to select the Blinky implementation */ #define BLINKY_IMPL 2 /*--------------------------------------------------------------------------*/ #if BLINKY_IMPL == 1 /* Blinky implementation closest matching the traditional blocking approach */ static void Blinky_init(Blinky * const me, SST_Evt const * const ie) { (void)ie; /* unused parameter */ SST_TimeEvt_arm(&me->te1, 1U, 0U); } /*..........................................................................*/ static void Blinky_dispatch(Blinky * const me, SST_Evt const * const e) { switch (e->sig) { case TIMEOUT1_SIG: { BSP_ledOn(); SST_TimeEvt_arm(&me->te2, BSP_TICKS_PER_SEC / 4U, 0U); break; } case TIMEOUT2_SIG: { BSP_ledOff(); SST_TimeEvt_arm(&me->te1, BSP_TICKS_PER_SEC * 3U/4U, 0U); break; } default: { DBC_ERROR(200); break; } } } /*--------------------------------------------------------------------------*/ #elif BLINKY_IMPL == 2 /* Blinky implementation with two periodic time events with offset */ static void Blinky_init(Blinky * const me, SST_Evt const * const ie) { (void)ie; /* unused parameter */ SST_TimeEvt_arm(&me->te1, 1U, BSP_TICKS_PER_SEC); SST_TimeEvt_arm(&me->te2, 1U + (BSP_TICKS_PER_SEC/4U), BSP_TICKS_PER_SEC); } /*..........................................................................*/ static void Blinky_dispatch(Blinky * const me, SST_Evt const * const e) { switch (e->sig) { case TIMEOUT1_SIG: { BSP_ledOn(); break; } case TIMEOUT2_SIG: { BSP_ledOff(); break; } default: { DBC_ERROR(200); break; } } } /*--------------------------------------------------------------------------*/ #else #error "Wrong definition of the macro BLINKY_VERSION" #endif ================================================ FILE: sst_c/examples/blinky/blinky.h ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #ifndef BLINKY_H_ #define BLINKY_H_ #include "dbc_assert.h" /* Design By Contract (DBC) assertions */ enum Signals { TIMEOUT1_SIG, TIMEOUT2_SIG, /* ... */ MAX_SIG /* the last signal */ }; void Blinky_instantiate(void); extern SST_Task * const AO_Blinky; /* opaque task pointer */ #endif /* BLINKY_H_ */ ================================================ FILE: sst_c/examples/blinky/bsp.h ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #ifndef BSP_H_ #define BSP_H_ #define BSP_TICKS_PER_SEC 1000U void BSP_init(void); void BSP_ledOn(void); void BSP_ledOff(void); #endif /* BSP_H_ */ ================================================ FILE: sst_c/examples/blinky/bsp_nucleo-l053r8.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example for STM32 NUCLEO-L053R8 * * Q u a n t u m L e a P s * ------------------------ * Modern Embedded Software * * Copyright (C) 2005 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" #include "bsp.h" #include "blinky.h" #include "stm32l0xx.h" /* CMSIS-compliant header file for the MCU used */ /* add other drivers if necessary... */ //DBC_MODULE_NAME("bsp_nucleo-l053r8") /* for DBC assertions in this module */ /* Local-scope defines -----------------------------------------------------*/ /* test pins on GPIO PA */ #define LED_PIN 5U /* LED LD2-Green */ /* ISRs used in the application ============================================*/ void SysTick_Handler(void); /* prototype */ void SysTick_Handler(void) { /* system clock tick ISR */ SST_TimeEvt_tick(); /* process all SST time events */ } /* Assertion handler ======================================================*/ DBC_NORETURN void DBC_fault_handler(char const * const module, int const label) { /* * NOTE: add here your application-specific error handling */ (void)module; (void)label; /* set PRIMASK to disable interrupts and stop SST right here */ __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { /* keep blinking LED2 */ BSP_ledOn(); /* turn LED2 on */ uint32_t volatile ctr; for (ctr = 10000U; ctr > 0U; --ctr) { } BSP_ledOff(); /* turn LED2 off */ for (ctr = 10000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } /*..........................................................................*/ void assert_failed(char const * const module, int const label);/* prototype */ void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } /* SST task activations ====================================================*/ /* preprocessor switch to choose between regular and reserved IRQs */ #define REGULAR_IRQS #ifdef REGULAR_IRQS /* repurpose regular IRQs for SST Tasks */ /* prototypes */ void PVD_IRQHandler(void); void PVD_IRQHandler(void) { SST_Task_activate(AO_Blinky); } #else /* use reserved IRQs for SST Tasks */ /* prototypes */ void Reserved14_IRQHandler(void); void Reserved14_IRQHandler(void) { SST_Task_activate(AO_Blinky); } #endif /* BSP functions ===========================================================*/ void BSP_init(void) { /* Configure the MPU to prevent NULL-pointer dereferencing * see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu */ MPU->RBAR = 0x0U /* base address (NULL) */ | MPU_RBAR_VALID_Msk /* valid region */ | (MPU_RBAR_REGION_Msk & 7U); /* region #7 */ MPU->RASR = (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1) region */ | (0x0U << MPU_RASR_AP_Pos) /* no-access region */ | MPU_RASR_ENABLE_Msk; /* region enable */ MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk /* enable background region */ | MPU_CTRL_ENABLE_Msk; /* enable the MPU */ __ISB(); __DSB(); /* assign IRQs to tasks. NOTE: critical for SST... */ #ifdef REGULAR_IRQS /* repurpose regular IRQs for SST Tasks */ SST_Task_setIRQ(AO_Blinky, PVD_IRQn); #else /* use reserved IRQs for SST Tasks */ SST_Task_setIRQ(AO_Blinky, 14U); #endif /* enable GPIO port PA clock */ RCC->IOPENR |= (1U << 0U); /* set all used GPIOA pins as push-pull output, no pull-up, pull-down */ GPIOA->MODER &= ~(3U << 2U*LED_PIN); GPIOA->MODER |= (1U << 2U*LED_PIN); GPIOA->OTYPER &= ~(1U << LED_PIN); GPIOA->PUPDR &= ~(3U << 2U*LED_PIN); } /*..........................................................................*/ void BSP_ledOn(void) { GPIOA->BSRR = (1U << LED_PIN); } /* LED2 */ void BSP_ledOff(void) { GPIOA->BSRR = (1U << (LED_PIN + 16U)); } /* SST callbacks ===========================================================*/ void SST_onStart(void) { SystemCoreClockUpdate(); /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ SysTick_Config((SystemCoreClock / BSP_TICKS_PER_SEC) + 1U); /* set priorities of ISRs used in the system */ NVIC_SetPriority(SysTick_IRQn, 0U); /* ... */ } /*..........................................................................*/ void SST_onIdle(void) { #ifdef NDEBUG /* Put the CPU and peripherals to the low-power mode. * you might need to customize the clock management for your application, * see the datasheet for your particular Cortex-M MCU. */ __WFI(); /* Wait-For-Interrupt */ #endif } ================================================ FILE: sst_c/examples/blinky/gnu/nucleo-l053r8.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST/C) on NUCLEO-L053R8, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-01-22 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f nucleo-l053r8.mak # make -f nucleo-l053r8.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky TARGET := nucleo-l053r8 #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ sst.c \ sst_port.c \ main.c \ blinky.c \ bsp_nucleo-l053r8.c \ system_stm32l0xx.c \ startup_stm32l053xx.c # C++ source files CPP_SRCS := LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m0plus ARM_FPU := FLOAT_ABI := #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst_c/examples/blinky/iar/nucleo-l053r8.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst_c/examples/blinky/iar/nucleo-l053r8.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Debug Application $PROJ_DIR$\..\blinky.c $PROJ_DIR$\..\blinky.h $PROJ_DIR$\..\bsp.h $PROJ_DIR$\..\bsp_nucleo-l053r8.c $PROJ_DIR$\..\main.c nucleo-l053r8 $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\iar\startup_stm32l053xx.s $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c sst $PROJ_DIR$\..\..\..\src\sst.c sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.c $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.h ================================================ FILE: sst_c/examples/blinky/iar/nucleo-l053r8.eww ================================================ $WS_DIR$\nucleo-l053r8.ewp ================================================ FILE: sst_c/examples/blinky/main.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky.h" /* application shared interface */ /*..........................................................................*/ int main() { SST_init(); /* initialize the SST kernel */ BSP_init(); /* initialize the Board Support Package */ /* instantiate and start all SST tasks... */ Blinky_instantiate(); static SST_Evt const *blinkyQSto[10]; /* Event queue storage */ SST_Task_start( AO_Blinky, /* AO pointer to start */ 1U, /* SST-priority */ blinkyQSto, /* storage for the AO's queue */ ARRAY_NELEM(blinkyQSto), /* queue length */ (void *)0); /* initialization event (not used) */ return SST_Task_run(); /* run the SST tasks */ /* NOTE; in embedded systems SST_Task_run() should not return */ } ================================================ FILE: sst_c/examples/blinky_button/armclang/ek-tm4c123gxl.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 ek-tm4c123gxl 0x4 ARM-ADS 12000000 1 1 1 0 0 1 65535 0 0 0 79 66 8 .\build_ek-tm4c123gxl\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 4 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 0 0 19 BIN\lmidk-agdi.dll 0 DLGUARM 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 UL2CM3 UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0TM4C123_256 -FL040000 -FS00 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM) 0 DLGTARM (1010=2431,200,2881,757,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=1881,651,2358,966,0) 0 ARMDBGFLAGS 0 lmidk-agdi -U0E10259B -O4686 -S5 -FO29 1 2 0x20000960 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Applicatioin 1 0 0 0 1 1 1 0 0 0 ..\main.c main.c 0 0 1 2 5 0 0 0 ..\blinky_button.h blinky_button.h 0 0 1 3 1 0 0 0 ..\blinky1.c blinky1.c 0 0 1 4 1 0 0 0 ..\blinky3.c blinky3.c 0 0 1 5 5 0 0 0 ..\bsp.h bsp.h 0 0 1 6 1 0 0 0 ..\bsp_ek-tm4c123gxl.c bsp_ek-tm4c123gxl.c 0 0 1 7 1 0 0 0 ..\button2a.c button2a.c 0 0 1 8 1 0 0 0 ..\button2b.c button2b.c 0 0 ek-tm4c123gxl 1 0 0 0 2 9 2 0 0 0 ..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s startup_TM4C123GH6PM.s 0 0 2 10 1 0 0 0 ..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c system_TM4C123GH6PM.c 0 0 2 11 5 0 0 0 ..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h TM4C123GH6PM.h 0 0 sst 1 0 0 0 3 12 1 0 0 0 ..\..\..\src\sst.c sst.c 0 0 sst_port 1 0 0 0 4 13 1 0 0 0 ..\..\..\ports\arm-cm\sst_port.c sst_port.c 0 0 4 14 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.h sst_port.h 0 0
================================================ FILE: sst_c/examples/blinky_button/armclang/ek-tm4c123gxl.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
ek-tm4c123gxl 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 TM4C123GH6PM Texas Instruments Keil.TM4C_DFP.1.1.0 http://www.keil.com/pack/ IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0TM4C123_256 -FS00 -FL040000 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM)) 0 $$Device:TM4C123GH6PM$Device\Include\TM4C123\TM4C123.h $$Device:TM4C123GH6PM$SVD\TM4C123\TM4C123GH6PM.svd 0 0 0 0 0 0 1 .\build_ek-tm4c123gxl\ blinky_button 1 0 0 1 1 .\build_ek-tm4c123gxl\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -MPU DCM.DLL -pCM4 SARMCM3.DLL -MPU TCM.DLL -pCM4 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL "" () 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M4" 0 0 0 1 1 0 0 2 0 0 0 0 8 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x8000 1 0x0 0x40000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x40000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x8000 0 0x0 0x0 0 1 0 0 1 0 0 0 0 0 3 0 1 0 0 0 3 3 0 0 0 0 0 -Wno-c11-extensions -Wno-padded __FPU_PRESENT ..;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\ek-tm4c123gxl 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Applicatioin main.c 1 ..\main.c blinky_button.h 5 ..\blinky_button.h blinky1.c 1 ..\blinky1.c blinky3.c 1 ..\blinky3.c bsp.h 5 ..\bsp.h bsp_ek-tm4c123gxl.c 1 ..\bsp_ek-tm4c123gxl.c button2a.c 1 ..\button2a.c button2b.c 1 ..\button2b.c ek-tm4c123gxl startup_TM4C123GH6PM.s 2 ..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s system_TM4C123GH6PM.c 1 ..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c TM4C123GH6PM.h 5 ..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h sst sst.c 1 ..\..\..\src\sst.c sst_port sst_port.c 1 ..\..\..\ports\arm-cm\sst_port.c sst_port.h 5 ..\..\..\ports\arm-cm\sst_port.h ek-tm4c123gxl 1
================================================ FILE: sst_c/examples/blinky_button/armclang/nucleo-c031c6.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 nucleo-c031c6 0x4 ARM-ADS 12000000 1 1 0 1 0 1 65535 0 0 0 79 66 8 .\build_nucleo-c031c6\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 ST-LINKIII-KEIL_SWO -U-O206 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 UL2CM3 UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) 0 lmidk-agdi -U0E10259B -O4622 -S3 -FO29 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=1150,195,1600,752,0)(1007=-1,-1,-1,-1,0)(1008=1224,174,1600,410,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS 0 0 120 1
134219768
0 0 0 0 0 1 ..\bsp_nucleo-c031c6.c \\blinky_button\../bsp_nucleo-c031c6.c\120
1 0 0 1
134221496
0 0 0 0 0 1
0 1 OS_curr 1 1 OS_next 2 1 OS_readySet 1 2 0x200000f0 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 2 10000000
Application 1 0 0 0 1 1 1 0 0 0 ..\blinky1.c blinky1.c 0 0 1 2 1 0 0 0 ..\blinky3.c blinky3.c 0 0 1 3 5 0 0 0 ..\bsp.h bsp.h 0 0 1 4 1 0 0 0 ..\button2a.c button2a.c 0 0 1 5 1 0 0 0 ..\button2b.c button2b.c 0 0 1 6 1 0 0 0 ..\main.c main.c 0 0 1 7 1 0 0 0 ..\bsp_nucleo-c031c6.c bsp_nucleo-c031c6.c 0 0 nucleo-c031c6 1 0 0 0 2 8 5 0 0 0 ..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h stm32c031xx.h 0 0 2 9 1 0 0 0 ..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c system_stm32c0xx.c 0 0 2 10 2 0 0 0 ..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s startup_stm32c031xx.s 0 0 sst 1 0 0 0 3 11 1 0 0 0 ..\..\..\src\sst.c sst.c 0 0 sst_port 1 0 0 0 4 12 1 0 0 0 ..\..\..\ports\arm-cm\sst_port.c sst_port.c 0 0 4 13 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.h sst_port.h 0 0
================================================ FILE: sst_c/examples/blinky_button/armclang/nucleo-c031c6.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
nucleo-c031c6 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32C031C6Tx STMicroelectronics Keil.STM32C0xx_DFP.1.0.0 https://www.keil.com/pack/ IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) 0 $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd 0 0 0 0 0 0 1 .\build_nucleo-c031c6\ blinky_button 1 0 0 1 1 .\build_nucleo-c031c6\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-c031c6\blinky_button.bin .\build_nucleo-c031c6\blinky_button.axf 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP-MPU DARMCM1.DLL -pCM0+ SARMCM3.DLL -MPU TARMCM1.DLL -pCM0+ 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL "" () 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M0+" 0 0 0 1 1 0 0 0 0 0 0 0 8 1 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x3000 1 0x8000000 0x8000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x8000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x3000 0 0x0 0x0 0 0 0 0 1 0 0 0 0 0 3 0 1 1 0 0 3 3 0 0 0 0 0 -Wconditional-uninitialized -Wsometimes-uninitialized .;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-c031c6 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Application blinky1.c 1 ..\blinky1.c blinky3.c 1 ..\blinky3.c bsp.h 5 ..\bsp.h button2a.c 1 ..\button2a.c button2b.c 1 ..\button2b.c main.c 1 ..\main.c bsp_nucleo-c031c6.c 1 ..\bsp_nucleo-c031c6.c nucleo-c031c6 stm32c031xx.h 5 ..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h system_stm32c0xx.c 1 ..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c startup_stm32c031xx.s 2 ..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s sst sst.c 1 ..\..\..\src\sst.c sst_port sst_port.c 1 ..\..\..\ports\arm-cm\sst_port.c sst_port.h 5 ..\..\..\ports\arm-cm\sst_port.h ek-tm4c123gxl 1
================================================ FILE: sst_c/examples/blinky_button/armclang/nucleo-h743zi.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 arm-nucleo-h743zi 0x4 ARM-ADS 12000000 1 1 1 0 0 1 65535 0 0 0 79 66 8 .\build_nucleo-h743zi\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 0 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 UL2CM3 UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0STM32H7x_2048 -FL0200000 -FS08000000 -FP0($$Device:STM32H743ZITx$CMSIS\Flash\STM32H7x_2048.FLM) 0 ST-LINKIII-KEIL_SWO -U0675FF504955857567065746 -O8399 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P2 -N00("ARM CoreSight SW-DP (ARM Core") -D00(6BA02477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20010000 -FC1000 -FN1 -FF0STM32H7x_2048.FLM -FS08000000 -FL0200000 -FP0($$Device:STM32H743ZITx$CMSIS\Flash\STM32H7x_2048.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=2367,534,2817,1091,1)(6017=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(6016=-1,-1,-1,-1,0)(1012=3268,1338,3745,1653,0) 0 ARMDBGFLAGS 0 0 67 1
134221976
0 0 0 0 0 1 ..\..\..\ports\arm-cm\sst_port.c \\blinky_button\../../../ports/arm-cm/sst_port.c\67
0 1 nvic_prio_shift 1 2 0xE000ED08 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 10000000
Applicatioin 1 0 0 0 1 1 5 0 0 0 ..\blinky_button.h blinky_button.h 0 0 1 2 1 0 0 0 ..\blinky1.c blinky1.c 0 0 1 3 1 0 0 0 ..\blinky3.c blinky3.c 0 0 1 4 5 0 0 0 ..\bsp.h bsp.h 0 0 1 5 1 0 0 0 ..\bsp_nucleo-h743zi.c bsp_nucleo-h743zi.c 0 0 1 6 1 0 0 0 ..\button2a.c button2a.c 0 0 1 7 1 0 0 0 ..\button2b.c button2b.c 0 0 1 8 1 0 0 0 ..\main.c main.c 0 0 nucleo-h743zi 1 0 0 0 2 9 2 0 0 0 ..\..\..\..\3rd_party\nucleo-h743zi\arm\startup_stm32h743xx.s startup_stm32h743xx.s 0 0 2 10 5 0 0 0 ..\..\..\..\3rd_party\nucleo-h743zi\stm32h743xx.h stm32h743xx.h 0 0 2 11 1 0 0 0 ..\..\..\..\3rd_party\nucleo-h743zi\system_stm32h7xx.c system_stm32h7xx.c 0 0 sst 1 0 0 0 3 12 1 0 0 0 ..\..\..\src\sst.c sst.c 0 0 sst_port 1 0 0 0 4 13 1 0 0 0 ..\..\..\ports\arm-cm\sst_port.c sst_port.c 0 0 4 14 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.h sst_port.h 0 0
================================================ FILE: sst_c/examples/blinky_button/armclang/nucleo-h743zi.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
arm-nucleo-h743zi 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32H743ZITx STMicroelectronics Keil.STM32H7xx_DFP.3.0.0 http://www.keil.com/pack/ IRAM(0x20000000,0x00020000) IRAM2(0x24000000,0x00080000) IROM(0x08000000,0x00200000) CPUTYPE("Cortex-M7") FPU3(DFPU) CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32H7x_2048 -FS08000000 -FL0200000 -FP0($$Device:STM32H743ZITx$CMSIS\Flash\STM32H7x_2048.FLM)) 0 $$Device:STM32H743ZITx$Drivers\CMSIS\Device\ST\STM32H7xx\Include\stm32h7xx.h $$Device:STM32H743ZITx$CMSIS\SVD\STM32H7x3.svd 0 0 0 0 0 0 1 .\build_nucleo-h743zi\ blinky_button 1 0 0 1 1 .\build_nucleo-h743zi\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-h743zi\blinky_button.bin .\build_nucleo-h743zi\blinky_button.axf 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP -MPU DCM.DLL -pCM7 SARMCM3.DLL -MPU TCM.DLL -pCM7 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL "" () 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M7" 0 0 0 1 1 0 0 3 0 0 1 0 8 0 0 0 0 3 4 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x20000 1 0x8000000 0x200000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x200000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x20000 0 0x24000000 0x80000 0 1 0 0 1 0 0 0 0 0 3 0 1 0 0 0 3 3 0 0 0 0 0 STM32H743xx .;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-h743zi 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Applicatioin blinky_button.h 5 ..\blinky_button.h blinky1.c 1 ..\blinky1.c blinky3.c 1 ..\blinky3.c bsp.h 5 ..\bsp.h bsp_nucleo-h743zi.c 1 ..\bsp_nucleo-h743zi.c button2a.c 1 ..\button2a.c button2b.c 1 ..\button2b.c main.c 1 ..\main.c nucleo-h743zi startup_stm32h743xx.s 2 ..\..\..\..\3rd_party\nucleo-h743zi\arm\startup_stm32h743xx.s stm32h743xx.h 5 ..\..\..\..\3rd_party\nucleo-h743zi\stm32h743xx.h system_stm32h7xx.c 1 ..\..\..\..\3rd_party\nucleo-h743zi\system_stm32h7xx.c sst sst.c 1 ..\..\..\src\sst.c sst_port sst_port.c 1 ..\..\..\ports\arm-cm\sst_port.c sst_port.h 5 ..\..\..\ports\arm-cm\sst_port.h nucleo-h743zi 1
================================================ FILE: sst_c/examples/blinky_button/armclang/nucleo-l053r8.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 nucleo-l053r8 0x4 ARM-ADS 12000000 1 1 0 1 0 1 65535 0 0 0 79 66 8 .\build_nucleo-l053r8\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 UL2CM3 UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM)) 0 ST-LINKIII-KEIL_SWO -U066CFF484951775087074312 -O8431 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P2 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC800 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=1702,853,2113,1355,0)(1007=2082,245,2289,466,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS 0 0 132 1
0
0 0 0 0 0 0 ..\..\..\ports\arm-cm\sst_port.c
1 2 0xE000E400 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 10000000
Application 1 0 0 0 1 1 5 0 0 0 ..\blinky_button.h blinky_button.h 0 0 1 2 1 0 0 0 ..\blinky1.c blinky1.c 0 0 1 3 1 0 0 0 ..\blinky3.c blinky3.c 0 0 1 4 5 0 0 0 ..\bsp.h bsp.h 0 0 1 5 1 0 0 0 ..\bsp_nucleo-l053r8.c bsp_nucleo-l053r8.c 0 0 1 6 1 0 0 0 ..\button2a.c button2a.c 0 0 1 7 1 0 0 0 ..\button2b.c button2b.c 0 0 1 8 1 0 0 0 ..\main.c main.c 0 0 nucleo-l053r8 1 0 0 0 2 9 2 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s startup_stm32l053xx.s 0 0 2 10 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l0xx.h 0 0 2 11 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h stm32l053xx.h 0 0 2 12 1 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c system_stm32l0xx.c 0 0 sst 1 0 0 0 3 13 1 0 0 0 ..\..\..\src\sst.c sst.c 0 0 3 14 5 0 0 0 ..\..\..\..\include\sst.h sst.h 0 0 sst_port 1 0 0 0 4 15 1 0 0 0 ..\..\..\ports\arm-cm\sst_port.c sst_port.c 0 0 4 16 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.h sst_port.h 0 0
================================================ FILE: sst_c/examples/blinky_button/armclang/nucleo-l053r8.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
nucleo-l053r8 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32L053R8Tx STMicroelectronics Keil.STM32L0xx_DFP.2.2.0 http://www.keil.com/pack/ IRAM(0x20000000,0x00002000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$Flash\STM32L0xx_64.FLM)) 0 $$Device:STM32L053R8Tx$Device\Include\stm32l0xx.h $$Device:STM32L053R8Tx$SVD\STM32L053x.svd 0 0 0 0 0 0 1 .\build_nucleo-l053r8\ blinky_button 1 0 0 1 1 .\build_nucleo-l053r8\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-l053r8\blinky_button.bin .\build_nucleo-l053r8\blinky_button.axf 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP DARMCM1.DLL -pCM0+ SARMCM3.DLL TARMCM1.DLL -pCM0+ 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M0+" 0 0 0 1 1 0 0 0 0 0 0 0 8 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 1 0x8000000 0x10000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x10000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 0 0x0 0x0 0 5 0 0 1 0 0 0 0 0 4 0 1 0 0 0 3 3 0 0 0 0 0 -Wno-padded .;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-l053r8 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Application blinky_button.h 5 ..\blinky_button.h blinky1.c 1 ..\blinky1.c blinky3.c 1 ..\blinky3.c bsp.h 5 ..\bsp.h bsp_nucleo-l053r8.c 1 ..\bsp_nucleo-l053r8.c button2a.c 1 ..\button2a.c button2b.c 1 ..\button2b.c main.c 1 ..\main.c nucleo-l053r8 startup_stm32l053xx.s 2 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s stm32l0xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l053xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h system_stm32l0xx.c 1 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c sst sst.c 1 ..\..\..\src\sst.c sst.h 5 ..\..\..\..\include\sst.h sst_port sst_port.c 1 ..\..\..\ports\arm-cm\sst_port.c sst_port.h 5 ..\..\..\ports\arm-cm\sst_port.h nucleo-l053r8 1
================================================ FILE: sst_c/examples/blinky_button/blinky1.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky_button.h" /* application shared interface */ DBC_MODULE_NAME("blinky1") /* for DBC assertions in this module */ /*..........................................................................*/ typedef struct { /* Blinky1 task */ SST_Task super; /* inherit SST_Task */ SST_TimeEvt te; /* time event for generating TIMEOUT events */ uint16_t toggles; /* number of toggles to perform for TIMEOUT event */ } Blinky1; static void Blinky1_ctor(Blinky1 * const me); static void Blinky1_init(Blinky1 * const me, SST_Evt const * const ie); static void Blinky1_dispatch(Blinky1 * const me, SST_Evt const * const e); /*..........................................................................*/ static Blinky1 Blinky1_inst; /* the Blinky instance */ SST_Task * const AO_Blinky1 = &Blinky1_inst.super; /* opaque AO pointer */ void Blinky1_instantiate(void) { Blinky1_ctor(&Blinky1_inst); } /*..........................................................................*/ static void Blinky1_ctor(Blinky1 * const me) { SST_Task_ctor( &me->super, (SST_Handler)&Blinky1_init, (SST_Handler)&Blinky1_dispatch); SST_TimeEvt_ctor(&me->te, TIMEOUT_SIG, &me->super); } /*..........................................................................*/ static void Blinky1_init(Blinky1 * const me, SST_Evt const * const ie) { /* the initial event must be provided and must be WORKLOAD_SIG */ DBC_REQUIRE(300, (ie != (SST_Evt const *)0) && (ie->sig == BLINKY_WORK_SIG)); SST_TimeEvt_arm(&me->te, SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks, SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks); me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->toggles; } /*..........................................................................*/ static void Blinky1_dispatch(Blinky1 * const me, SST_Evt const * const e) { switch (e->sig) { case TIMEOUT_SIG: { for (uint16_t i = me->toggles; i > 0U; --i) { /* just to exercise SST task scheduler lock... */ SST_LockKey key = SST_Task_lock(3U); BSP_d5on(); BSP_d5off(); SST_Task_unlock(key); } break; } case BLINKY_WORK_SIG: { BSP_d5on(); SST_TimeEvt_arm(&me->te, SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks, SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks); me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->toggles; BSP_d5off(); break; } default: { DBC_ERROR(500); /* unexpected event */ break; } } } ================================================ FILE: sst_c/examples/blinky_button/blinky3.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky_button.h" /* application shared interface */ DBC_MODULE_NAME("blinky3") /* for DBC assertions in this module */ /*..........................................................................*/ typedef struct { /* Blinky3 task */ SST_Task super; /* inherit SST_Task */ SST_TimeEvt te; /* time event for generating TIMEOUT events */ uint16_t toggles; /* number of toggles to perform for TIMEOUT event */ } Blinky3; static void Blinky3_ctor(Blinky3 * const me); static void Blinky3_init(Blinky3 * const me, SST_Evt const * const ie); static void Blinky3_dispatch(Blinky3 * const me, SST_Evt const * const e); /*..........................................................................*/ static Blinky3 Blinky3_inst; /* the Blinky3 instance */ SST_Task * const AO_Blinky3 = &Blinky3_inst.super; /* opaque AO pointer */ void Blinky3_instantiate(void) { Blinky3_ctor(&Blinky3_inst); } /*..........................................................................*/ static void Blinky3_ctor(Blinky3 * const me) { SST_Task_ctor( &me->super, (SST_Handler)&Blinky3_init, (SST_Handler)&Blinky3_dispatch); SST_TimeEvt_ctor(&me->te, TIMEOUT_SIG, &me->super); } /*..........................................................................*/ static void Blinky3_init(Blinky3 * const me, SST_Evt const * const ie) { /* the initial event must be provided and must be WORKLOAD_SIG */ DBC_REQUIRE(300, (ie != (SST_Evt const *)0) && (ie->sig == BLINKY_WORK_SIG)); SST_TimeEvt_arm(&me->te, SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks, SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks); me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->toggles; } /*..........................................................................*/ static void Blinky3_dispatch(Blinky3 * const me, SST_Evt const * const e) { switch (e->sig) { case TIMEOUT_SIG: { for (uint16_t i = me->toggles; i > 0U; --i) { BSP_d2on(); BSP_d2off(); } break; } case BLINKY_WORK_SIG: { BSP_d2on(); SST_TimeEvt_arm(&me->te, SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks, SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks); me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->toggles; BSP_d2off(); break; } default: { DBC_ERROR(500); /* unexpected event */ break; } } } ================================================ FILE: sst_c/examples/blinky_button/blinky_button.h ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #ifndef BLINKY_BUTTON_H_ #define BLINKY_BUTTON_H_ #include "dbc_assert.h" /* Design By Contract (DBC) assertions */ enum Signals { TIMEOUT_SIG, BUTTON_PRESSED_SIG, BUTTON_RELEASED_SIG, BLINKY_WORK_SIG, FORWARD_PRESSED_SIG, FORWARD_RELEASED_SIG, /* ... */ MAX_SIG /* the last signal */ }; typedef struct { SST_Evt super; /* inherit SST_Evt */ uint16_t toggles; /* number of toggles of the signal */ uint8_t ticks; /* number of clock ticks between */ } BlinkyWorkEvt; typedef struct { SST_Evt super; /* inherit SST_Evt */ uint16_t toggles; /* number of toggles of the signal */ } ButtonWorkEvt; void Blinky1_instantiate(void); extern SST_Task * const AO_Blinky1; /* opaque task pointer */ void Blinky3_instantiate(void); extern SST_Task * const AO_Blinky3; /* opaque task pointer */ void Button2a_instantiate(void); extern SST_Task * const AO_Button2a; /* opaque task pointer */ void Button2b_instantiate(void); extern SST_Task * const AO_Button2b; /* opaque task pointer */ #endif /* BLINKY_BUTTON_H_ */ ================================================ FILE: sst_c/examples/blinky_button/bsp.h ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #ifndef BSP_H_ #define BSP_H_ #define BSP_TICKS_PER_SEC 1000U void BSP_init(void); void BSP_d1on(void); void BSP_d1off(void); void BSP_d2on(void); void BSP_d2off(void); void BSP_d3on(void); void BSP_d3off(void); void BSP_d4on(void); void BSP_d4off(void); void BSP_d5on(void); void BSP_d5off(void); void BSP_d6on(void); void BSP_d6off(void); /* immutable events for Blinky tasks */ SST_Evt const *BSP_getWorkEvtBlinky1(uint8_t num); SST_Evt const *BSP_getWorkEvtBlinky3(uint8_t num); #endif /* BSP_H_ */ ================================================ FILE: sst_c/examples/blinky_button/bsp_ek-tm4c123gxl.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example for TivaC TM4C123GXL * * Q u a n t u m L e a P s * ------------------------ * Modern Embedded Software * * Copyright (C) 2005 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" #include "bsp.h" #include "blinky_button.h" #include "TM4C123GH6PM.h" /* the device specific header (TI) */ #include /* to exercise the FPU */ /* add other drivers if necessary... */ DBC_MODULE_NAME("bsp_ek-tm4c123gxl") /* for DBC assertions in this module */ /* Local-scope defines -----------------------------------------------------*/ /* test pins on GPIOF */ #define TST1_PIN (1U << 1U) /* LED Red */ #define TST2_PIN (1U << 2U) /* LED Blue */ /* test pins on GPIOD */ #define TST3_PIN (1U << 0U) #define TST4_PIN (1U << 1U) #define TST5_PIN (1U << 2U) /* test pins on GPIOF */ #define TST6_PIN (1U << 3U) /* LED Green */ /* Button on the board on GPIOF */ #define BTN_SW1 (1U << 4) /* ISRs used in the application ============================================*/ void SysTick_Handler(void); /* prototype */ void SysTick_Handler(void) { /* system clock tick ISR */ BSP_d1on(); SST_TimeEvt_tick(); /* process all SST time events */ /* Perform the debouncing of buttons. The algorithm for debouncing * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle * and Michael Barr, page 71. */ static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = ~GPIOF_AHB->DATA_Bits[BTN_SW1]; uint32_t tmp = buttons.depressed; /* save the debounced depressed */ buttons.depressed |= (buttons.previous & current); /* set depressed */ buttons.depressed &= (buttons.previous | current); /* clear released */ buttons.previous = current; /* update the history */ tmp ^= buttons.depressed; /* changed debounced depressed */ if ((tmp & BTN_SW1) != 0U) { /* debounced SW1 state changed? */ if ((buttons.depressed & BTN_SW1) != 0U) { /* is SW1 depressed? */ /* immutable button-press event */ static ButtonWorkEvt const pressEvt = { .super.sig = BUTTON_PRESSED_SIG, .toggles = 60U }; /* immutable forward-press event */ static ButtonWorkEvt const fPressEvt = { .super.sig = FORWARD_PRESSED_SIG, .toggles = 60U }; SST_Task_post(AO_Button2a, &fPressEvt.super); SST_Task_post(AO_Button2a, &pressEvt.super); } else { /* B1 is released */ /* immutable button-release event */ static ButtonWorkEvt const releaseEvt = { .super.sig = BUTTON_RELEASED_SIG, .toggles = 80U }; /* immutable forward-release event */ static ButtonWorkEvt const fReleaseEvt = { .super.sig = FORWARD_RELEASED_SIG, .toggles = 80U }; SST_Task_post(AO_Button2a, &fReleaseEvt.super); SST_Task_post(AO_Button2a, &releaseEvt.super); } } BSP_d1off(); } /* Assertion handler ======================================================*/ DBC_NORETURN void DBC_fault_handler(char const * const module, int const label) { /* * NOTE: add here your application-specific error handling */ (void)module; (void)label; /* set PRIMASK to disable interrupts and stop SST right here */ __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { /* keep blinking LED2 */ BSP_d6on(); /* turn LED2 on */ uint32_t volatile ctr; for (ctr = 1000000U; ctr > 0U; --ctr) { } BSP_d6off(); /* turn LED2 off */ for (ctr = 1000000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } /*..........................................................................*/ void assert_failed(char const * const module, int const label);/* prototype */ void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } /* SST task activations ====================================================*/ /* repurpose regular IRQs for SST Tasks */ /* prototypes */ void PWM1Gen0_IRQHandler(void); void PWM1Gen1_IRQHandler(void); void PWM1Gen2_IRQHandler(void); void PWM1Gen3_IRQHandler(void); void PWM1Gen0_IRQHandler(void) { SST_Task_activate(AO_Blinky3); } void PWM1Gen1_IRQHandler(void) { SST_Task_activate(AO_Button2b); } void PWM1Gen2_IRQHandler(void) { SST_Task_activate(AO_Button2a); } void PWM1Gen3_IRQHandler(void) { SST_Task_activate(AO_Blinky1); } /* BSP functions ===========================================================*/ void BSP_init(void) { /* Configure the MPU to prevent NULL-pointer dereferencing * see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu */ MPU->RBAR = 0x0U /* base address (NULL) */ | MPU_RBAR_VALID_Msk /* valid region */ | (MPU_RBAR_REGION_Msk & 7U); /* region #7 */ MPU->RASR = (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1) region */ | (0x0U << MPU_RASR_AP_Pos) /* no-access region */ | MPU_RASR_ENABLE_Msk; /* region enable */ MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk /* enable background region */ | MPU_CTRL_ENABLE_Msk; /* enable the MPU */ __ISB(); __DSB(); /* assign IRQs to tasks. NOTE: critical for SST... */ SST_Task_setIRQ(AO_Blinky3, PWM1_0_IRQn); SST_Task_setIRQ(AO_Button2b, PWM1_1_IRQn); SST_Task_setIRQ(AO_Button2a, PWM1_2_IRQn); SST_Task_setIRQ(AO_Blinky1, PWM1_3_IRQn); SYSCTL->RCGCGPIO |= (1U << 5U); /* enable Run mode for GPIOF */ SYSCTL->RCGCGPIO |= (1U << 3U); /* enable Run mode for GPIOD */ __ISB(); __DSB(); SYSCTL->GPIOHBCTL |= (1U << 5); /* enable AHB for GPIOF */ SYSCTL->GPIOHBCTL |= (1U << 3); /* enable AHB for GPIOD */ __ISB(); __DSB(); /* configure test pins on GPIOF (digital output) */ GPIOF_AHB->DIR |= (TST1_PIN | TST2_PIN | TST6_PIN); GPIOF_AHB->DEN |= (TST1_PIN | TST2_PIN | TST6_PIN); /* configure button on GPIOF (digital input) */ GPIOF_AHB->DIR &= ~(BTN_SW1); /* input */ GPIOF_AHB->DEN |= (BTN_SW1); /* digital enable */ GPIOF_AHB->PUR |= (BTN_SW1); /* pull-up resistor enable */ /* configure test pins on GPIOD (digital output) */ GPIOD_AHB->DIR |= (TST3_PIN | TST4_PIN | TST5_PIN); GPIOD_AHB->DEN |= (TST3_PIN | TST4_PIN | TST5_PIN); } /*..........................................................................*/ #if defined __ARMCC_VERSION #elif defined __GNUC__ uint32_t __errno; /* GNU-ARM needs this to link sqrtf() */ #endif static void exerciseFPU(float x) { /* exercise the single-precision FPU by calculating the identity: * sqrt(x) == x / sqrt(x) for x > 0 */ float tmp1 = sqrtf(x); /* single-precision sqrt() */ float tmp2 = x / tmp1; DBC_ENSURE(200, (tmp1 - 1e-4f <= tmp2) && (tmp2 <= tmp1 + 1e-4f)); } /*..........................................................................*/ void BSP_d1on(void) { /* LED-Red */ GPIOF_AHB->DATA_Bits[TST1_PIN] = 0xFFU; /* don't use the FPU in the ISR */ } void BSP_d1off(void) { GPIOF_AHB->DATA_Bits[TST1_PIN] = 0x00U; } /*..........................................................................*/ void BSP_d2on(void) { /* LED-Blue */ GPIOF_AHB->DATA_Bits[TST2_PIN] = 0xFFU; exerciseFPU(1.2345f); } void BSP_d2off(void) { GPIOF_AHB->DATA_Bits[TST2_PIN] = 0x00U; } /*..........................................................................*/ void BSP_d3on(void) { GPIOD_AHB->DATA_Bits[TST3_PIN] = 0xFFU; exerciseFPU(0.345f); } void BSP_d3off(void) { GPIOD_AHB->DATA_Bits[TST3_PIN] = 0x00U; } /*..........................................................................*/ void BSP_d4on(void) { GPIOD_AHB->DATA_Bits[TST4_PIN] = 0xFFU; exerciseFPU(0.456f); } void BSP_d4off(void) { GPIOD_AHB->DATA_Bits[TST4_PIN] = 0x00U; } /*..........................................................................*/ void BSP_d5on(void) { GPIOD_AHB->DATA_Bits[TST5_PIN] = 0xFFU; exerciseFPU(1.567f); } void BSP_d5off(void) { GPIOD_AHB->DATA_Bits[TST5_PIN] = 0x00U; } /*..........................................................................*/ void BSP_d6on(void) { /* LED2-Green */ GPIOF_AHB->DATA_Bits[TST6_PIN] = 0xFFU; exerciseFPU(1.2345f); } void BSP_d6off(void) { GPIOF_AHB->DATA_Bits[TST6_PIN] = 0x00U; } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky1(uint8_t num) { /* immutable work events for Blinky1 */ static BlinkyWorkEvt const workBlinky1[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 40U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 30U, .ticks = 7U, } }; DBC_REQUIRE(500, num < ARRAY_NELEM(workBlinky1)); /* must be in range */ return &workBlinky1[num].super; } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky3(uint8_t num) { /* immutable work events for Blinky3 */ static BlinkyWorkEvt const workBlinky3[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 20U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 10U, .ticks = 3U, } }; DBC_REQUIRE(600, num < ARRAY_NELEM(workBlinky3)); /* must be in range */ return &workBlinky3[num].super; } /* SST callbacks ===========================================================*/ void SST_onStart(void) { SystemCoreClockUpdate(); /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ SysTick_Config((SystemCoreClock / BSP_TICKS_PER_SEC) + 1U); /* set priorities of ISRs used in the system */ NVIC_SetPriority(SysTick_IRQn, 0U); /* ... */ } /*..........................................................................*/ void SST_onIdle(void) { BSP_d6on(); /* turn LED-Green on */ #ifdef NDEBUG /* Put the CPU and peripherals to the low-power mode. * you might need to customize the clock management for your application, * see the datasheet for your particular Cortex-M MCU. */ BSP_d6off(); /* turn LED-Green off */ __WFI(); /* Wait-For-Interrupt */ BSP_d6on(); /* turn LED-Green on */ #endif BSP_d6off(); /* turn LED-Green off */ } ================================================ FILE: sst_c/examples/blinky_button/bsp_nucleo-c031c6.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example for STM32 NUCLEO-C031C6 * * Q u a n t u m L e a P s * ------------------------ * Modern Embedded Software * * Copyright (C) 2005 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" #include "bsp.h" #include "blinky_button.h" #include "stm32c0xx.h" /* CMSIS-compliant header file for the MCU used */ /* add other drivers if necessary... */ DBC_MODULE_NAME("bsp_nucleo-c031c6") /* Local-scope defines -----------------------------------------------------*/ /* test pins on GPIO PA */ #define TST1_PIN 7U #define TST2_PIN 6U #define TST3_PIN 4U #define TST4_PIN 1U #define TST5_PIN 0U #define TST6_PIN 5U /* LED L4-Green */ /* buttons on GPIO PC */ #define B1_PIN 13U /* ISRs used in the application ============================================*/ void SysTick_Handler(void); /* prototype */ void SysTick_Handler(void) { /* system clock tick ISR */ BSP_d1on(); SST_TimeEvt_tick(); /* process all SST time events */ /* Perform the debouncing of buttons. The algorithm for debouncing * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle * and Michael Barr, page 71. */ static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = ~GPIOC->IDR; /* read GPIO PortC */ uint32_t tmp = buttons.depressed; /* save the debounced depressed */ buttons.depressed |= (buttons.previous & current); /* set depressed */ buttons.depressed &= (buttons.previous | current); /* clear released */ buttons.previous = current; /* update the history */ tmp ^= buttons.depressed; /* changed debounced depressed */ if ((tmp & (1U << B1_PIN)) != 0U) { /* debounced B1 state changed? */ if ((buttons.depressed & (1U << B1_PIN)) != 0U) { /* depressed? */ /* immutable button-press event */ static ButtonWorkEvt const pressEvt = { .super.sig = BUTTON_PRESSED_SIG, .toggles = 60U }; /* immutable forward-press event */ static ButtonWorkEvt const fPressEvt = { .super.sig = FORWARD_PRESSED_SIG, .toggles = 60U }; SST_Task_post(AO_Button2a, &fPressEvt.super); SST_Task_post(AO_Button2a, &pressEvt.super); } else { /* B1 is released */ /* immutable button-release event */ static ButtonWorkEvt const releaseEvt = { .super.sig = BUTTON_RELEASED_SIG, .toggles = 80U }; /* immutable forward-release event */ static ButtonWorkEvt const fReleaseEvt = { .super.sig = FORWARD_RELEASED_SIG, .toggles = 80U }; SST_Task_post(AO_Button2a, &fReleaseEvt.super); SST_Task_post(AO_Button2a, &releaseEvt.super); } } BSP_d1off(); } /* Assertion handler ======================================================*/ DBC_NORETURN void DBC_fault_handler(char const * const module, int const label) { /* * NOTE: add here your application-specific error handling */ (void)module; (void)label; /* set PRIMASK to disable interrupts and stop SST right here */ __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { /* keep blinking LED2 */ BSP_d6on(); /* turn LD4 on */ uint32_t volatile ctr; for (ctr = 100000U; ctr > 0U; --ctr) { } BSP_d6off(); /* turn LD4 off */ for (ctr = 100000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } /*..........................................................................*/ void assert_failed(char const * const module, int const label);/* prototype */ void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } /* SST task activations ====================================================*/ /* preprocessor switch to choose between regular and reserved IRQs */ #define REGULAR_IRQS #ifdef REGULAR_IRQS /* repurpose regular IRQs for SST Tasks */ /* prototypes */ void TIM3_IRQHandler(void); void TIM14_IRQHandler(void); void TIM16_IRQHandler(void); void TIM17_IRQHandler(void); void TIM3_IRQHandler(void) { SST_Task_activate(AO_Blinky3); } void TIM14_IRQHandler(void) { SST_Task_activate(AO_Button2b); } void TIM16_IRQHandler(void) { SST_Task_activate(AO_Button2a); } void TIM17_IRQHandler(void) { SST_Task_activate(AO_Blinky1); } #else /* use reserved IRQs for SST Tasks */ /* prototypes */ void Reserved1_IRQHandler(void); void Reserved8_IRQHandler(void); void Reserved15_IRQHandler(void); void Reserved17_IRQHandler(void); void Reserved1_IRQHandler(void) { SST_Task_activate(AO_Blinky3); } void Reserved8_IRQHandler(void) { SST_Task_activate(AO_Button2b); } void Reserved15_IRQHandler(void) { SST_Task_activate(AO_Button2a); } void Reserved17_IRQHandler(void) { SST_Task_activate(AO_Blinky1); } #endif /* BSP functions ===========================================================*/ void BSP_init(void) { /* Configure the MPU to prevent NULL-pointer dereferencing * see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu */ MPU->RBAR = 0x0U /* base address (NULL) */ | MPU_RBAR_VALID_Msk /* valid region */ | (MPU_RBAR_REGION_Msk & 7U); /* region #7 */ MPU->RASR = (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1) region */ | (0x0U << MPU_RASR_AP_Pos) /* no-access region */ | MPU_RASR_ENABLE_Msk; /* region enable */ MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk /* enable background region */ | MPU_CTRL_ENABLE_Msk; /* enable the MPU */ __ISB(); __DSB(); /* assign IRQs to tasks. NOTE: critical for SST... */ #ifdef REGULAR_IRQS /* repurpose regular IRQs for SST Tasks */ SST_Task_setIRQ(AO_Blinky3, TIM3_IRQn); SST_Task_setIRQ(AO_Button2b, TIM14_IRQn); SST_Task_setIRQ(AO_Button2a, TIM16_IRQn); SST_Task_setIRQ(AO_Blinky1, TIM17_IRQn); #else /* use reserved IRQs for SST Tasks */ SST_Task_setIRQ(AO_Blinky3, 1U); SST_Task_setIRQ(AO_Button2b, 8U); SST_Task_setIRQ(AO_Button2a, 15U); SST_Task_setIRQ(AO_Blinky1, 17U); #endif /* enable GPIO port PA clock */ RCC->IOPENR |= (1U << 0U); /* set all used GPIOA pins as push-pull output, no pull-up, pull-down */ GPIOA->MODER &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); GPIOA->MODER |= ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); GPIOA->OTYPER &= ~((1U << TST1_PIN) | (1U << TST2_PIN) | (1U << TST3_PIN) | (1U << TST4_PIN) | (1U << TST5_PIN) | (1U << TST6_PIN)); GPIOA->OSPEEDR &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); GPIOA->OSPEEDR |= ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); GPIOA->PUPDR &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); /* enable GPIOC clock port for the Button B1 */ RCC->IOPENR |= (1U << 2U); /* configure Button B1 pin on GPIOC as input, no pull-up, pull-down */ GPIOC->MODER &= ~(3U << 2U*B1_PIN); GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); } /*..........................................................................*/ void BSP_d1on(void) { GPIOA->BSRR = (1U << TST1_PIN); } void BSP_d1off(void) { GPIOA->BSRR = (1U << (TST1_PIN + 16U)); } /*..........................................................................*/ void BSP_d2on(void) { GPIOA->BSRR = (1U << TST2_PIN); } void BSP_d2off(void) { GPIOA->BSRR = (1U << (TST2_PIN + 16U)); } /*..........................................................................*/ void BSP_d3on(void) { GPIOA->BSRR = (1U << TST3_PIN); } void BSP_d3off(void) { GPIOA->BSRR = (1U << (TST3_PIN + 16U)); } /*..........................................................................*/ void BSP_d4on(void) { GPIOA->BSRR = (1U << TST4_PIN); } void BSP_d4off(void) { GPIOA->BSRR = (1U << (TST4_PIN + 16U)); } /*..........................................................................*/ void BSP_d5on(void) { GPIOA->BSRR = (1U << TST5_PIN); } void BSP_d5off(void) { GPIOA->BSRR = (1U << (TST5_PIN + 16U)); } /*..........................................................................*/ void BSP_d6on(void) { GPIOA->BSRR = (1U << TST6_PIN); } /* LD4 */ void BSP_d6off(void) { GPIOA->BSRR = (1U << (TST6_PIN + 16U)); } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky1(uint8_t num) { /* immutable work events for Blinky1 */ static BlinkyWorkEvt const workBlinky1[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 40U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 30U, .ticks = 7U, } }; DBC_REQUIRE(500, num < ARRAY_NELEM(workBlinky1)); /* must be in range */ return &workBlinky1[num].super; } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky3(uint8_t num) { /* immutable work events for Blinky3 */ static BlinkyWorkEvt const workBlinky3[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 20U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 10U, .ticks = 3U, } }; DBC_REQUIRE(600, num < ARRAY_NELEM(workBlinky3)); /* must be in range */ return &workBlinky3[num].super; } /* SST callbacks ===========================================================*/ void SST_onStart(void) { SystemCoreClockUpdate(); /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ SysTick_Config((SystemCoreClock / BSP_TICKS_PER_SEC) + 1U); /* set priorities of ISRs used in the system */ NVIC_SetPriority(SysTick_IRQn, 0U); /* ... */ } /*..........................................................................*/ void SST_onIdle(void) { BSP_d6on(); /* turn LED2 on */ #ifdef NDEBUG /* Put the CPU and peripherals to the low-power mode. * you might need to customize the clock management for your application, * see the datasheet for your particular Cortex-M MCU. */ BSP_d6off(); /* turn LED2 off */ __WFI(); /* Wait-For-Interrupt */ BSP_d6on(); /* turn LED2 on */ #endif BSP_d6off(); /* turn LED2 off */ } ================================================ FILE: sst_c/examples/blinky_button/bsp_nucleo-h743zi.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example for STM32 NUCLEO-H743ZI * * Q u a n t u m L e a P s * ------------------------ * Modern Embedded Software * * Copyright (C) 2005 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" #include "bsp.h" #include "blinky_button.h" #include "stm32h743xx.h" /* CMSIS-compliant header file for the MCU used */ #include /* to exercise the FPU */ /* add other drivers if necessary... */ DBC_MODULE_NAME("bsp_nucleo-h743zi") /* for DBC assertions in this module */ /* Local-scope defines -----------------------------------------------------*/ /* test pins on GPIO PB */ #define TST1_PIN 0U /* PB.0 LED1-Green */ #define TST2_PIN 14U /* PB.14 LED3-Red */ #define TST3_PIN 4U #define TST4_PIN 5U #define TST5_PIN 6U #define TST6_PIN 7U /* PB.7 LED2-Blue */ /* buttons on GPIO PC */ #define B1_PIN 13U /* ISRs used in the application ============================================*/ void SysTick_Handler(void); /* prototype */ void SysTick_Handler(void) { /* system clock tick ISR */ BSP_d1on(); SST_TimeEvt_tick(); /* process all SST time events */ /* Perform the debouncing of buttons. The algorithm for debouncing * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle * and Michael Barr, page 71. */ static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = GPIOC->IDR; /* read GPIO PortC */ uint32_t tmp = buttons.depressed; /* save the debounced depressed */ buttons.depressed |= (buttons.previous & current); /* set depressed */ buttons.depressed &= (buttons.previous | current); /* clear released */ buttons.previous = current; /* update the history */ tmp ^= buttons.depressed; /* changed debounced depressed */ if ((tmp & (1U << B1_PIN)) != 0U) { /* debounced B1 state changed? */ if ((buttons.depressed & (1U << B1_PIN)) != 0U) { /* depressed? */ /* immutable button-press event */ static ButtonWorkEvt const pressEvt = { .super.sig = BUTTON_PRESSED_SIG, .toggles = 60U }; /* immutable forward-press event */ static ButtonWorkEvt const fPressEvt = { .super.sig = FORWARD_PRESSED_SIG, .toggles = 60U }; SST_Task_post(AO_Button2a, &fPressEvt.super); SST_Task_post(AO_Button2a, &pressEvt.super); } else { /* B1 is released */ /* immutable button-release event */ static ButtonWorkEvt const releaseEvt = { .super.sig = BUTTON_RELEASED_SIG, .toggles = 80U }; /* immutable forward-release event */ static ButtonWorkEvt const fReleaseEvt = { .super.sig = FORWARD_RELEASED_SIG, .toggles = 80U }; SST_Task_post(AO_Button2a, &fReleaseEvt.super); SST_Task_post(AO_Button2a, &releaseEvt.super); } } BSP_d1off(); } /* Assertion handler ======================================================*/ DBC_NORETURN void DBC_fault_handler(char const * const module, int const label) { /* * NOTE: add here your application-specific error handling */ (void)module; (void)label; /* set PRIMASK to disable interrupts and stop SST right here */ __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { /* keep blinking LED2 */ BSP_d6on(); /* turn LED2 on */ uint32_t volatile ctr; for (ctr = 1000000U; ctr > 0U; --ctr) { } BSP_d6off(); /* turn LED2 off */ for (ctr = 1000000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } /*..........................................................................*/ void assert_failed(char const * const module, int const label);/* prototype */ void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } /* SST task activations ====================================================*/ /* preprocessor switch to choose between regular and reserved IRQs */ #define REGULAR_IRQS #ifdef REGULAR_IRQS /* repurpose regular IRQs for SST Tasks */ /* prototypes */ void OTG_FS_EP1_OUT_IRQHandler(void); void OTG_FS_EP1_IN_IRQHandler(void); void OTG_FS_WKUP_IRQHandler(void); void OTG_FS_IRQHandler(void); void OTG_FS_EP1_OUT_IRQHandler(void) { SST_Task_activate(AO_Blinky3); } void OTG_FS_EP1_IN_IRQHandler(void) { SST_Task_activate(AO_Button2b); } void OTG_FS_WKUP_IRQHandler(void) { SST_Task_activate(AO_Button2a); } void OTG_FS_IRQHandler(void) { SST_Task_activate(AO_Blinky1); } #else /* use reserved IRQs for SST Tasks */ /* prototypes */ void Reserved42_IRQHandler(void); void Reserved64_IRQHandler(void); void Reserved65_IRQHandler(void); void Reserved66_IRQHandler(void); void Reserved42_IRQHandler(void) { SST_Task_activate(AO_Blinky3); } void Reserved64_IRQHandler(void) { SST_Task_activate(AO_Button2b); } void Reserved65_IRQHandler(void) { SST_Task_activate(AO_Button2a); } void Reserved66_IRQHandler(void) { SST_Task_activate(AO_Blinky1); } #endif /* BSP functions ===========================================================*/ void BSP_init(void) { /* Configure the MPU to prevent NULL-pointer dereferencing * see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu */ MPU->RBAR = 0x0U /* base address (NULL) */ | MPU_RBAR_VALID_Msk /* valid region */ | (MPU_RBAR_REGION_Msk & 7U); /* region #7 */ MPU->RASR = (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1) region */ | (0x0U << MPU_RASR_AP_Pos) /* no-access region */ | MPU_RASR_ENABLE_Msk; /* region enable */ MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk /* enable background region */ | MPU_CTRL_ENABLE_Msk; /* enable the MPU */ __ISB(); __DSB(); SCB_EnableICache(); /* Enable I-Cache */ SCB_EnableDCache(); /* Enable D-Cache */ /* assign IRQs to tasks. NOTE: critical for SST... */ #ifdef REGULAR_IRQS /* repurpose regular IRQs for SST Tasks */ SST_Task_setIRQ(AO_Blinky3, OTG_FS_EP1_OUT_IRQn); SST_Task_setIRQ(AO_Button2b, OTG_FS_EP1_IN_IRQn); SST_Task_setIRQ(AO_Button2a, OTG_FS_WKUP_IRQn); SST_Task_setIRQ(AO_Blinky1, OTG_FS_IRQn); #else /* use reserved IRQs for SST Tasks */ SST_Task_setIRQ(AO_Blinky3, 42U); SST_Task_setIRQ(AO_Button2b, 64U); SST_Task_setIRQ(AO_Button2a, 65U); SST_Task_setIRQ(AO_Blinky1, 66U); #endif /* enable GPIOB port clock for LEds and test pins */ RCC->AHB4ENR |= RCC_AHB4ENR_GPIOBEN; /* set all used GPIOB pins as push-pull output, no pull-up, pull-down */ GPIOB->MODER &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); GPIOB->MODER |= ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); GPIOB->OTYPER &= ~((1U << TST1_PIN) | (1U << TST2_PIN) | (1U << TST3_PIN) | (1U << TST4_PIN) | (1U << TST5_PIN) | (1U << TST6_PIN)); GPIOB->PUPDR &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); /* enable GPIOC clock port for the Button B1 */ RCC->AHB4ENR |= RCC_AHB4ENR_GPIOCEN; /* configure Button B1 pin on GPIOC as input, no pull-up, pull-down */ GPIOC->MODER &= ~(3U << 2U*B1_PIN); GPIOC->PUPDR &= ~(GPIO_PUPDR_PUPD0 << 2U*B1_PIN); GPIOC->PUPDR |= (2U << 2U*B1_PIN); } /*..........................................................................*/ static void exerciseFPU(double x) { /* exercise the double-precision FPU by calculating the identity: * sin(x)^2 + cos(x)^2 == 1.0 for any x */ double tmp = pow(sin(x), 2.0) + pow(cos(x), 2.0); DBC_ENSURE(200, (1.0 - 1e-4 < tmp) && (tmp < 1.0 + 1e-4)); } /*..........................................................................*/ void BSP_d1on(void) { /* LED1-Green */ GPIOB->BSRR = (1U << TST1_PIN); /* don't use the FPU in the ISR */ } void BSP_d1off(void) { GPIOB->BSRR = (1U << (TST1_PIN + 16U)); } /*..........................................................................*/ void BSP_d2on(void) { /* LED3-Red */ GPIOB->BSRR = (1U << TST2_PIN); exerciseFPU(-1.2345); } void BSP_d2off(void) { GPIOB->BSRR = (1U << (TST2_PIN + 16U)); } /*..........................................................................*/ void BSP_d3on(void) { GPIOB->BSRR = (1U << TST3_PIN); exerciseFPU(-12.345); } void BSP_d3off(void) { GPIOB->BSRR = (1U << (TST3_PIN + 16U)); } /*..........................................................................*/ void BSP_d4on(void) { GPIOB->BSRR = (1U << TST4_PIN); exerciseFPU(3.456); } void BSP_d4off(void) { GPIOB->BSRR = (1U << (TST4_PIN + 16U)); } /*..........................................................................*/ void BSP_d5on(void) { GPIOB->BSRR = (1U << TST5_PIN); exerciseFPU(4.567); } void BSP_d5off(void) { GPIOB->BSRR = (1U << (TST5_PIN + 16U)); } /*..........................................................................*/ void BSP_d6on(void) { /* LED2-Blue */ GPIOB->BSRR = (1U << TST6_PIN); exerciseFPU(1.2345); } void BSP_d6off(void) { GPIOB->BSRR = (1U << (TST6_PIN + 16U)); } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky1(uint8_t num) { /* immutable work events for Blinky1 */ static BlinkyWorkEvt const workBlinky1[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 40U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 30U, .ticks = 7U, } }; DBC_REQUIRE(500, num < ARRAY_NELEM(workBlinky1)); /* must be in range */ return &workBlinky1[num].super; } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky3(uint8_t num) { /* immutable work events for Blinky3 */ static BlinkyWorkEvt const workBlinky3[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 20U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 10U, .ticks = 3U, } }; DBC_REQUIRE(600, num < ARRAY_NELEM(workBlinky3)); /* must be in range */ return &workBlinky3[num].super; } /* SST callbacks ===========================================================*/ void SST_onStart(void) { SystemCoreClockUpdate(); /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ SysTick_Config((SystemCoreClock / BSP_TICKS_PER_SEC) + 1U); /* set priorities of ISRs used in the system */ NVIC_SetPriority(SysTick_IRQn, 0U); /* ... */ } /*..........................................................................*/ void SST_onIdle(void) { BSP_d6on(); /* turn LED2 on */ #ifdef NDEBUG /* Put the CPU and peripherals to the low-power mode. * you might need to customize the clock management for your application, * see the datasheet for your particular Cortex-M MCU. */ BSP_d6off(); /* turn LED2 off */ __WFI(); /* Wait-For-Interrupt */ BSP_d6on(); /* turn LED2 on */ #endif BSP_d6off(); /* turn LED2 off */ } ================================================ FILE: sst_c/examples/blinky_button/bsp_nucleo-l053r8.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example for STM32 NUCLEO-L053R8 * * Q u a n t u m L e a P s * ------------------------ * Modern Embedded Software * * Copyright (C) 2005 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" #include "bsp.h" #include "blinky_button.h" #include "stm32l0xx.h" /* CMSIS-compliant header file for the MCU used */ /* add other drivers if necessary... */ DBC_MODULE_NAME("bsp_nucleo-l053r8") /* for DBC assertions in this module */ /* Local-scope defines -----------------------------------------------------*/ /* test pins on GPIO PA */ #define TST1_PIN 7U #define TST2_PIN 6U #define TST3_PIN 4U #define TST4_PIN 1U #define TST5_PIN 0U #define TST6_PIN 5U /* LED LD2-Green */ /* buttons on GPIO PC */ #define B1_PIN 13U /* ISRs used in the application ============================================*/ void SysTick_Handler(void); /* prototype */ void SysTick_Handler(void) { /* system clock tick ISR */ BSP_d1on(); SST_TimeEvt_tick(); /* process all SST time events */ /* Perform the debouncing of buttons. The algorithm for debouncing * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle * and Michael Barr, page 71. */ static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = ~GPIOC->IDR; /* read GPIO PortC */ uint32_t tmp = buttons.depressed; /* save the debounced depressed */ buttons.depressed |= (buttons.previous & current); /* set depressed */ buttons.depressed &= (buttons.previous | current); /* clear released */ buttons.previous = current; /* update the history */ tmp ^= buttons.depressed; /* changed debounced depressed */ if ((tmp & (1U << B1_PIN)) != 0U) { /* debounced B1 state changed? */ if ((buttons.depressed & (1U << B1_PIN)) != 0U) { /* depressed? */ /* immutable button-press event */ static ButtonWorkEvt const pressEvt = { .super.sig = BUTTON_PRESSED_SIG, .toggles = 60U }; /* immutable forward-press event */ static ButtonWorkEvt const fPressEvt = { .super.sig = FORWARD_PRESSED_SIG, .toggles = 60U }; SST_Task_post(AO_Button2a, &fPressEvt.super); SST_Task_post(AO_Button2a, &pressEvt.super); } else { /* B1 is released */ /* immutable button-release event */ static ButtonWorkEvt const releaseEvt = { .super.sig = BUTTON_RELEASED_SIG, .toggles = 80U }; /* immutable forward-release event */ static ButtonWorkEvt const fReleaseEvt = { .super.sig = FORWARD_RELEASED_SIG, .toggles = 80U }; SST_Task_post(AO_Button2a, &fReleaseEvt.super); SST_Task_post(AO_Button2a, &releaseEvt.super); } } BSP_d1off(); } /* Assertion handler ======================================================*/ DBC_NORETURN void DBC_fault_handler(char const * const module, int const label) { /* * NOTE: add here your application-specific error handling */ (void)module; (void)label; /* set PRIMASK to disable interrupts and stop SST right here */ __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { /* keep blinking LED2 */ BSP_d6on(); /* turn LED2 on */ uint32_t volatile ctr; for (ctr = 10000U; ctr > 0U; --ctr) { } BSP_d6off(); /* turn LED2 off */ for (ctr = 10000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } /*..........................................................................*/ void assert_failed(char const * const module, int const label);/* prototype */ void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } /* SST task activations ====================================================*/ /* preprocessor switch to choose between regular and reserved IRQs */ #define REGULAR_IRQS #ifdef REGULAR_IRQS /* repurpose regular IRQs for SST Tasks */ /* prototypes */ void PVD_IRQHandler(void); void RTC_IRQHandler(void); void TSC_IRQHandler(void); void I2C2_IRQHandler(void); void PVD_IRQHandler(void) { SST_Task_activate(AO_Blinky3); } void RTC_IRQHandler(void) { SST_Task_activate(AO_Button2b); } void TSC_IRQHandler(void) { SST_Task_activate(AO_Button2a); } void I2C2_IRQHandler(void) { SST_Task_activate(AO_Blinky1); } #else /* use reserved IRQs for SST Tasks */ /* prototypes */ void Reserved14_IRQHandler(void); void Reserved16_IRQHandler(void); void Reserved18_IRQHandler(void); void Reserved19_IRQHandler(void); void Reserved14_IRQHandler(void) { SST_Task_activate(AO_Blinky3); } void Reserved16_IRQHandler(void) { SST_Task_activate(AO_Button2b); } void Reserved18_IRQHandler(void) { SST_Task_activate(AO_Button2a); } void Reserved19_IRQHandler(void) { SST_Task_activate(AO_Blinky1); } #endif /* BSP functions ===========================================================*/ void BSP_init(void) { /* Configure the MPU to prevent NULL-pointer dereferencing * see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu */ MPU->RBAR = 0x0U /* base address (NULL) */ | MPU_RBAR_VALID_Msk /* valid region */ | (MPU_RBAR_REGION_Msk & 7U); /* region #7 */ MPU->RASR = (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1) region */ | (0x0U << MPU_RASR_AP_Pos) /* no-access region */ | MPU_RASR_ENABLE_Msk; /* region enable */ MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk /* enable background region */ | MPU_CTRL_ENABLE_Msk; /* enable the MPU */ __ISB(); __DSB(); /* assign IRQs to tasks. NOTE: critical for SST... */ #ifdef REGULAR_IRQS /* repurpose regular IRQs for SST Tasks */ SST_Task_setIRQ(AO_Blinky3, PVD_IRQn); SST_Task_setIRQ(AO_Button2b, RTC_IRQn); SST_Task_setIRQ(AO_Button2a, TSC_IRQn); SST_Task_setIRQ(AO_Blinky1, I2C2_IRQn); #else /* use reserved IRQs for SST Tasks */ SST_Task_setIRQ(AO_Blinky3, 14U); SST_Task_setIRQ(AO_Button2b, 16U); SST_Task_setIRQ(AO_Button2a, 18U); SST_Task_setIRQ(AO_Blinky1, 19U); #endif /* enable GPIO port PA clock */ RCC->IOPENR |= (1U << 0U); /* set all used GPIOA pins as push-pull output, no pull-up, pull-down */ GPIOA->MODER &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); GPIOA->MODER |= ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); GPIOA->OTYPER &= ~((1U << TST1_PIN) | (1U << TST2_PIN) | (1U << TST3_PIN) | (1U << TST4_PIN) | (1U << TST5_PIN) | (1U << TST6_PIN)); GPIOA->PUPDR &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); /* enable GPIOC clock port for the Button B1 */ RCC->IOPENR |= (1U << 2U); /* configure Button B1 pin on GPIOC as input, no pull-up, pull-down */ GPIOC->MODER &= ~(3U << 2U*B1_PIN); GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); } /*..........................................................................*/ void BSP_d1on(void) { GPIOA->BSRR = (1U << TST1_PIN); } void BSP_d1off(void) { GPIOA->BSRR = (1U << (TST1_PIN + 16U)); } /*..........................................................................*/ void BSP_d2on(void) { GPIOA->BSRR = (1U << TST2_PIN); } void BSP_d2off(void) { GPIOA->BSRR = (1U << (TST2_PIN + 16U)); } /*..........................................................................*/ void BSP_d3on(void) { GPIOA->BSRR = (1U << TST3_PIN); } void BSP_d3off(void) { GPIOA->BSRR = (1U << (TST3_PIN + 16U)); } /*..........................................................................*/ void BSP_d4on(void) { GPIOA->BSRR = (1U << TST4_PIN); } void BSP_d4off(void) { GPIOA->BSRR = (1U << (TST4_PIN + 16U)); } /*..........................................................................*/ void BSP_d5on(void) { GPIOA->BSRR = (1U << TST5_PIN); } void BSP_d5off(void) { GPIOA->BSRR = (1U << (TST5_PIN + 16U)); } /*..........................................................................*/ void BSP_d6on(void) { GPIOA->BSRR = (1U << TST6_PIN); } /* LED2 */ void BSP_d6off(void) { GPIOA->BSRR = (1U << (TST6_PIN + 16U)); } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky1(uint8_t num) { /* immutable work events for Blinky1 */ static BlinkyWorkEvt const workBlinky1[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 40U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 30U, .ticks = 7U, } }; DBC_REQUIRE(500, num < ARRAY_NELEM(workBlinky1)); /* must be in range */ return &workBlinky1[num].super; } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky3(uint8_t num) { /* immutable work events for Blinky3 */ static BlinkyWorkEvt const workBlinky3[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 20U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 10U, .ticks = 3U, } }; DBC_REQUIRE(600, num < ARRAY_NELEM(workBlinky3)); /* must be in range */ return &workBlinky3[num].super; } /* SST callbacks ===========================================================*/ void SST_onStart(void) { SystemCoreClockUpdate(); /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ SysTick_Config((SystemCoreClock / BSP_TICKS_PER_SEC) + 1U); /* set priorities of ISRs used in the system */ NVIC_SetPriority(SysTick_IRQn, 0U); /* ... */ } /*..........................................................................*/ void SST_onIdle(void) { BSP_d6on(); /* turn LED2 on */ #ifdef NDEBUG /* Put the CPU and peripherals to the low-power mode. * you might need to customize the clock management for your application, * see the datasheet for your particular Cortex-M MCU. */ BSP_d6off(); /* turn LED2 off */ __WFI(); /* Wait-For-Interrupt */ BSP_d6on(); /* turn LED2 on */ #endif BSP_d6off(); /* turn LED2 off */ } ================================================ FILE: sst_c/examples/blinky_button/button2a.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky_button.h" /* application shared interface */ DBC_MODULE_NAME("button2a") /* for DBC assertions in this module */ /*..........................................................................*/ typedef struct { /* Button2a task */ SST_Task super; /* inherit SST_Task */ /* add internal variables for this AO... */ } Button2a; static void Button2a_ctor(Button2a * const me); static void Button2a_init(Button2a * const me, SST_Evt const * const ie); static void Button2a_dispatch(Button2a * const me, SST_Evt const * const e); /*..........................................................................*/ static Button2a Button2a_inst; /* the Button2a instance */ SST_Task * const AO_Button2a = &Button2a_inst.super; /* opaque AO pointer */ void Button2a_instantiate(void) { Button2a_ctor(&Button2a_inst); } /*..........................................................................*/ static void Button2a_ctor(Button2a * const me) { SST_Task_ctor( &me->super, (SST_Handler)&Button2a_init, (SST_Handler)&Button2a_dispatch); } /*..........................................................................*/ static void Button2a_init(Button2a * const me, SST_Evt const * const ie) { (void)me; (void)ie; } /*..........................................................................*/ static void Button2a_dispatch(Button2a * const me, SST_Evt const * const e) { (void)me; switch (e->sig) { case BUTTON_PRESSED_SIG: { BSP_d4on(); /* Button2a --> Blinky1 */ SST_Task_post(AO_Blinky1, BSP_getWorkEvtBlinky1(1U)); BSP_d4off(); for (uint16_t i = SST_EVT_DOWNCAST(ButtonWorkEvt, e)->toggles; i > 0U; --i) { BSP_d4on(); BSP_d4off(); } break; } case FORWARD_PRESSED_SIG: { BSP_d4on(); /* immutable event can be forwarded to another Task */ SST_Task_post(AO_Button2b, e); /* Button2a --> Button2b */ BSP_d4off(); break; } case BUTTON_RELEASED_SIG: { BSP_d4on(); /* Button2a --> Blinky1 */ SST_Task_post(AO_Blinky1, BSP_getWorkEvtBlinky1(0U)); BSP_d4off(); for (uint16_t i = SST_EVT_DOWNCAST(ButtonWorkEvt, e)->toggles; i > 0U; --i) { BSP_d4on(); BSP_d4off(); } break; } case FORWARD_RELEASED_SIG: { BSP_d4on(); /* immutable event can be forwarded to another Task */ SST_Task_post(AO_Button2b, e); /* Button2a --> Button2b */ BSP_d4off(); break; } default: { DBC_ERROR(500); /* unexpected event */ break; } } } ================================================ FILE: sst_c/examples/blinky_button/button2b.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky_button.h" /* application shared interface */ DBC_MODULE_NAME("button2b") /* for DBC assertions in this module */ /*..........................................................................*/ typedef struct { /* Button2b task */ SST_Task super; /* inherit SST_Task */ /* add internal variables for this AO... */ } Button2b; static void Button2b_ctor(Button2b * const me); static void Button2b_init(Button2b * const me, SST_Evt const * const e); static void Button2b_dispatch(Button2b * const me, SST_Evt const * const e); /*..........................................................................*/ static Button2b Button2b_inst; /* the Button2b instance */ SST_Task * const AO_Button2b = &Button2b_inst.super; /* opaque AO pointer */ void Button2b_instantiate(void) { Button2b_ctor(&Button2b_inst); } /*..........................................................................*/ static void Button2b_ctor(Button2b * const me) { SST_Task_ctor( &me->super, (SST_Handler)&Button2b_init, (SST_Handler)&Button2b_dispatch); } /*..........................................................................*/ static void Button2b_init(Button2b * const me, SST_Evt const * const ie) { (void)me; (void)ie; } /*..........................................................................*/ static void Button2b_dispatch(Button2b * const me, SST_Evt const * const e) { switch (e->sig) { case FORWARD_PRESSED_SIG: { BSP_d3on(); /* Button2b --> Blinky3 */ SST_Task_post(AO_Blinky3, BSP_getWorkEvtBlinky3(1U)); BSP_d3off(); for (uint16_t i = SST_EVT_DOWNCAST(ButtonWorkEvt, e)->toggles; i > 0U; --i) { BSP_d3on(); BSP_d3off(); } break; } case FORWARD_RELEASED_SIG: { BSP_d3on(); /* Button2b --> Blinky3 */ SST_Task_post(AO_Blinky3, BSP_getWorkEvtBlinky3(0U)); BSP_d3off(); for (uint16_t i = SST_EVT_DOWNCAST(ButtonWorkEvt, e)->toggles; i > 0U; --i) { BSP_d3on(); BSP_d3off(); } break; } default: { DBC_ERROR(500); /* unexpected event */ break; } } } ================================================ FILE: sst_c/examples/blinky_button/gnu/ek-tm4c123gxl.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST/C) on TM4C123GXL, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-01-25 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f ek-tm4c123gxl.mak # make -f ek-tm4c123gxl.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky_button TARGET := ek-tm4c123gxl #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ sst.c \ sst_port.c \ main.c \ blinky1.c \ blinky3.c \ button2a.c \ button2b.c \ bsp_ek-tm4c123gxl.c \ system_TM4C123GH6PM.c \ startup_TM4C123GH6PM.c # C++ source files CPP_SRCS := LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := -DTARGET_IS_TM4C123_RB1 # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m4 ARM_FPU := -mfpu=vfp FLOAT_ABI := -mfloat-abi=softfp #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst_c/examples/blinky_button/gnu/flash_ek-tm4c123gxl.bat ================================================ ::============================================================================ :: Batch file to program the flash of EK-TM4C123GXL :: :: NOTE: requires the LMFlash programmer (included in QTools for Windows) :: @echo off setlocal @echo Load a given binary file to the flash of EK-TM4C123GXL @echo usage: flash binary-file @echo example: flash dbg\blinky-qk.bin ::---------------------------------------------------------------------------- :: NOTE: The following symbol LMFLASH assumes that LMFlash.exe can :: be found on the PATH. You might need to adjust this symbol to the :: location of the LMFlash utility on your machine :: set LMFLASH=LMFlash.exe if ["%~1"]==[""] ( @echo The binary file missing @goto end ) if not exist %~s1 ( @echo The binary file '%1' does not exist @goto end ) %LMFLASH% -q ek-tm4c123gxl -e -v -r %1 :end endlocal ================================================ FILE: sst_c/examples/blinky_button/gnu/nucleo-c031c6.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST/C) on NUCLEO-C031C6, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-02-01 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f nucleo-c031c6.mak # make -f nucleo-c031c6.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky_button TARGET := nucleo-c031c6 #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ sst.c \ sst_port.c \ main.c \ blinky1.c \ blinky3.c \ button2a.c \ button2b.c \ bsp_nucleo-c031c6.c \ system_stm32c0xx.c \ startup_stm32c031xx.c # C++ source files CPP_SRCS := LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := -DSTM32C031xx # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m0plus ARM_FPU := FLOAT_ABI := #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean: -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst_c/examples/blinky_button/gnu/nucleo-h743zi.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST/C) on NUCLEO-H743ZI, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-01-22 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f nucleo-h743zi.mak # make -f nucleo-h743zi.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky_button TARGET := nucleo-h743zi #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ sst.c \ sst_port.c \ main.c \ blinky1.c \ blinky3.c \ button2a.c \ button2b.c \ bsp_nucleo-h743zi.c \ startup_stm32h743xx.c \ system_stm32h7xx.c # C++ source files CPP_SRCS := LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := -DSTM32H743xx # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m7 ARM_FPU := -mfpu=fpv5-d16 FLOAT_ABI := -mfloat-abi=softfp #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst_c/examples/blinky_button/gnu/nucleo-l053r8.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST/C) on NUCLEO-L053R8, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-01-22 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f nucleo-l053r8.mak # make -f nucleo-l053r8.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky_button TARGET := nucleo-l053r8 #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ sst.c \ sst_port.c \ main.c \ blinky1.c \ blinky3.c \ button2a.c \ button2b.c \ bsp_nucleo-l053r8.c \ system_stm32l0xx.c \ startup_stm32l053xx.c # C++ source files CPP_SRCS := LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m0plus ARM_FPU := FLOAT_ABI := #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst_c/examples/blinky_button/iar/ek-tm4c123gxl.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst_c/examples/blinky_button/iar/ek-tm4c123gxl.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Application $PROJ_DIR$\..\blinky1.c $PROJ_DIR$\..\blinky3.c $PROJ_DIR$\..\blinky_button.h $PROJ_DIR$\..\bsp.h $PROJ_DIR$\..\bsp_ek-tm4c123gxl.c $PROJ_DIR$\..\button2a.c $PROJ_DIR$\..\button2b.c $PROJ_DIR$\..\main.c ek-tm4c123gxl $PROJ_DIR$\..\..\..\..\3rd_party\ek-tm4c123gxl\iar\startup_TM4C123GH6PM.s $PROJ_DIR$\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c $PROJ_DIR$\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h sst $PROJ_DIR$\..\..\..\src\sst.c sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.c $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.h ================================================ FILE: sst_c/examples/blinky_button/iar/ek-tm4c123gxl.eww ================================================ $WS_DIR$\ek-tm4c123gxl.ewp ================================================ FILE: sst_c/examples/blinky_button/iar/nucleo-c031c6.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst_c/examples/blinky_button/iar/nucleo-c031c6.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Debug Application $PROJ_DIR$\..\blinky1.c $PROJ_DIR$\..\blinky3.c $PROJ_DIR$\..\blinky_button.h $PROJ_DIR$\..\bsp.h $PROJ_DIR$\..\bsp_nucleo-c031c6.c $PROJ_DIR$\..\button2a.c $PROJ_DIR$\..\button2b.c $PROJ_DIR$\..\main.c nucleo-c031c6 $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-c031c6\iar\startup_stm32c031xx.s $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.h sst $PROJ_DIR$\..\..\..\src\sst.c sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.c $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.h ================================================ FILE: sst_c/examples/blinky_button/iar/nucleo-c031c6.eww ================================================ $WS_DIR$\nucleo-c031c6.ewp ================================================ FILE: sst_c/examples/blinky_button/iar/nucleo-h743zi.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst_c/examples/blinky_button/iar/nucleo-h743zi.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Debug Application $PROJ_DIR$\..\blinky1.c $PROJ_DIR$\..\blinky3.c $PROJ_DIR$\..\blinky_button.h $PROJ_DIR$\..\bsp.h $PROJ_DIR$\..\bsp_nucleo-h743zi.c $PROJ_DIR$\..\button2a.c $PROJ_DIR$\..\button2b.c $PROJ_DIR$\..\main.c nucleo-h743zi $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-h743zi\iar\startup_stm32h743xx.s $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-h743zi\stm32h743xx.h $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-h743zi\system_stm32h7xx.c sst $PROJ_DIR$\..\..\..\src\sst.c sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.c $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.h ================================================ FILE: sst_c/examples/blinky_button/iar/nucleo-h743zi.eww ================================================ $WS_DIR$\nucleo-h743zi.ewp ================================================ FILE: sst_c/examples/blinky_button/iar/nucleo-l053r8.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst_c/examples/blinky_button/iar/nucleo-l053r8.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Debug Application $PROJ_DIR$\..\blinky1.c $PROJ_DIR$\..\blinky3.c $PROJ_DIR$\..\blinky_button.h $PROJ_DIR$\..\bsp.h $PROJ_DIR$\..\bsp_nucleo-l053r8.c $PROJ_DIR$\..\button2a.c $PROJ_DIR$\..\button2b.c $PROJ_DIR$\..\main.c nucleo-l053r8 $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\iar\startup_stm32l053xx.s $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c sst $PROJ_DIR$\..\..\..\src\sst.c sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.c $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.h ================================================ FILE: sst_c/examples/blinky_button/iar/nucleo-l053r8.eww ================================================ $WS_DIR$\nucleo-l053r8.ewp ================================================ FILE: sst_c/examples/blinky_button/main.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky_button.h" /* application shared interface */ /*..........................................................................*/ int main() { SST_init(); /* initialize the SST kernel */ BSP_init(); /* initialize the Board Support Package */ /* instantiate and start all SST tasks... */ Blinky1_instantiate(); static SST_Evt const *blinky1QSto[10]; /* Event queue storage */ SST_Task_start( AO_Blinky1, /* AO pointer to start */ 1U, /* SST-priority */ blinky1QSto, /* storage for the AO's queue */ ARRAY_NELEM(blinky1QSto), /* queue length */ BSP_getWorkEvtBlinky1(0U)); /* initialization event */ Button2a_instantiate(); static SST_Evt const *button2aQSto[8]; /* Event queue storage */ SST_Task_start( AO_Button2a, /* AO pointer to start */ 2U, /* SST-priority */ button2aQSto, /* storage for the AO's queue */ ARRAY_NELEM(button2aQSto), /* queue length */ (SST_Evt const *)0); /* initialization event -- not used */ Button2b_instantiate(); static SST_Evt const *button2bQSto[6]; /* Event queue storage */ SST_Task_start( AO_Button2b, /* AO pointer to start */ 2U, /* SST-priority */ button2bQSto, /* storage for the AO's queue */ ARRAY_NELEM(button2bQSto), /* queue length */ (SST_Evt const *)0); /* initialization event -- not used */ Blinky3_instantiate(); static SST_Evt const *blinky3QSto[4]; /* Event queue storage */ SST_Task_start( AO_Blinky3, /* AO pointer to start */ 3U, /* SST-priority */ blinky3QSto, /* storage for the AO's queue */ ARRAY_NELEM(blinky3QSto), /* queue length */ BSP_getWorkEvtBlinky3(0U)); /* initialization event */ return SST_Task_run(); /* run the SST tasks */ /* NOTE; in embedded systems SST_Task_run() should not return */ } ================================================ FILE: sst_c/examples/blinky_button.X/.gitignore ================================================ # .gitignore file # MPLAB X IDE (Netbeans) specific **/*.X/~*.* **/*.X/build/ **/*.X/debug/ **/*.X/dist/ **/*.X/disassembly/ **/*.X/.generated_files/ **/*.X/nbproject/private/ **/*.X/nbproject/*.mk **/*.X/nbproject/*.bash **/*.X/nbproject/Makefile-genesis.properties # Object files *.o *.ko *.obj *.elf # Executables *.exe /.generated_files /build # KDE specific .directory # Misc .svn *.bak ================================================ FILE: sst_c/examples/blinky_button.X/Makefile ================================================ # # There exist several targets which are by default empty and which can be # used for execution of your targets. These targets are usually executed # before and after some main targets. They are: # # .build-pre: called before 'build' target # .build-post: called after 'build' target # .clean-pre: called before 'clean' target # .clean-post: called after 'clean' target # .clobber-pre: called before 'clobber' target # .clobber-post: called after 'clobber' target # .all-pre: called before 'all' target # .all-post: called after 'all' target # .help-pre: called before 'help' target # .help-post: called after 'help' target # # Targets beginning with '.' are not intended to be called on their own. # # Main targets can be executed directly, and they are: # # build build a specific configuration # clean remove built files from a configuration # clobber remove all built files # all build all configurations # help print help mesage # # Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and # .help-impl are implemented in nbproject/makefile-impl.mk. # # Available make variables: # # CND_BASEDIR base directory for relative paths # CND_DISTDIR default top distribution directory (build artifacts) # CND_BUILDDIR default top build directory (object files, ...) # CONF name of current configuration # CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) # CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) # CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) # CND_PACKAGE_DIR_${CONF} directory of package (current configuration) # CND_PACKAGE_NAME_${CONF} name of package (current configuration) # CND_PACKAGE_PATH_${CONF} path to package (current configuration) # # NOCDDL # Environment MKDIR=mkdir CP=cp CCADMIN=CCadmin RANLIB=ranlib # build build: .build-post .build-pre: # Add your pre 'build' code here... .build-post: .build-impl # Add your post 'build' code here... # clean clean: .clean-post .clean-pre: # Add your pre 'clean' code here... # WARNING: the IDE does not call this target since it takes a long time to # simply run make. Instead, the IDE removes the configuration directories # under build and dist directly without calling make. # This target is left here so people can do a clean when running a clean # outside the IDE. .clean-post: .clean-impl # Add your post 'clean' code here... # clobber clobber: .clobber-post .clobber-pre: # Add your pre 'clobber' code here... .clobber-post: .clobber-impl # Add your post 'clobber' code here... # all all: .all-post .all-pre: # Add your pre 'all' code here... .all-post: .all-impl # Add your post 'all' code here... # help help: .help-post .help-pre: # Add your pre 'help' code here... .help-post: .help-impl # Add your post 'help' code here... # include project implementation makefile include nbproject/Makefile-impl.mk # include project make variables include nbproject/Makefile-variables.mk ================================================ FILE: sst_c/examples/blinky_button.X/blinky1.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky_button.h" /* application shared interface */ DBC_MODULE_NAME("blinky1") /* for DBC assertions in this module */ /*..........................................................................*/ typedef struct { /* Blinky1 task */ SST_Task super; /* inherit SST_Task */ SST_TimeEvt te; /* time event for generating TIMEOUT events */ uint16_t toggles; /* number of toggles to perform for TIMEOUT event */ } Blinky1; static void Blinky1_ctor(Blinky1 * const me); static void Blinky1_init(Blinky1 * const me, SST_Evt const * const ie); static void Blinky1_dispatch(Blinky1 * const me, SST_Evt const * const e); /*..........................................................................*/ static Blinky1 Blinky1_inst; /* the Blinky instance */ SST_Task * const AO_Blinky1 = &Blinky1_inst.super; /* opaque AO pointer */ void Blinky1_instantiate(void) { Blinky1_ctor(&Blinky1_inst); } /*..........................................................................*/ static void Blinky1_ctor(Blinky1 * const me) { SST_Task_ctor( &me->super, (SST_Handler)&Blinky1_init, (SST_Handler)&Blinky1_dispatch); SST_TimeEvt_ctor(&me->te, TIMEOUT_SIG, &me->super); } /*..........................................................................*/ static void Blinky1_init(Blinky1 * const me, SST_Evt const * const ie) { /* the initial event must be provided and must be WORKLOAD_SIG */ DBC_REQUIRE(300, (ie != (SST_Evt const *)0) && (ie->sig == BLINKY_WORK_SIG)); SST_TimeEvt_arm(&me->te, SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks, SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks); me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->toggles; } /*..........................................................................*/ static void Blinky1_dispatch(Blinky1 * const me, SST_Evt const * const e) { switch (e->sig) { case TIMEOUT_SIG: { for (uint16_t i = me->toggles; i > 0U; --i) { /* just to exercise SST task scheduler lock... */ SST_LockKey key = SST_Task_lock(3U); BSP_d5on(); BSP_d5off(); SST_Task_unlock(key); } break; } case BLINKY_WORK_SIG: { BSP_d5on(); SST_TimeEvt_arm(&me->te, SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks, SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks); me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->toggles; BSP_d5off(); break; } default: { DBC_ERROR(500); /* unexpected event */ break; } } } ================================================ FILE: sst_c/examples/blinky_button.X/blinky3.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky_button.h" /* application shared interface */ DBC_MODULE_NAME("blinky3") /* for DBC assertions in this module */ /*..........................................................................*/ typedef struct { /* Blinky3 task */ SST_Task super; /* inherit SST_Task */ SST_TimeEvt te; /* time event for generating TIMEOUT events */ uint16_t toggles; /* number of toggles to perform for TIMEOUT event */ } Blinky3; static void Blinky3_ctor(Blinky3 * const me); static void Blinky3_init(Blinky3 * const me, SST_Evt const * const ie); static void Blinky3_dispatch(Blinky3 * const me, SST_Evt const * const e); /*..........................................................................*/ static Blinky3 Blinky3_inst; /* the Blinky3 instance */ SST_Task * const AO_Blinky3 = &Blinky3_inst.super; /* opaque AO pointer */ void Blinky3_instantiate(void) { Blinky3_ctor(&Blinky3_inst); } /*..........................................................................*/ static void Blinky3_ctor(Blinky3 * const me) { SST_Task_ctor( &me->super, (SST_Handler)&Blinky3_init, (SST_Handler)&Blinky3_dispatch); SST_TimeEvt_ctor(&me->te, TIMEOUT_SIG, &me->super); } /*..........................................................................*/ static void Blinky3_init(Blinky3 * const me, SST_Evt const * const ie) { /* the initial event must be provided and must be WORKLOAD_SIG */ DBC_REQUIRE(300, (ie != (SST_Evt const *)0) && (ie->sig == BLINKY_WORK_SIG)); SST_TimeEvt_arm(&me->te, SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks, SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks); me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->toggles; } /*..........................................................................*/ static void Blinky3_dispatch(Blinky3 * const me, SST_Evt const * const e) { switch (e->sig) { case TIMEOUT_SIG: { for (uint16_t i = me->toggles; i > 0U; --i) { BSP_d2on(); BSP_d2off(); } break; } case BLINKY_WORK_SIG: { BSP_d2on(); SST_TimeEvt_arm(&me->te, SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks, SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks); me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->toggles; BSP_d2off(); break; } default: { DBC_ERROR(500); /* unexpected event */ break; } } } ================================================ FILE: sst_c/examples/blinky_button.X/blinky_button.h ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #ifndef BLINKY_BUTTON_H_ #define BLINKY_BUTTON_H_ #include "dbc_assert.h" /* Design By Contract (DBC) assertions */ enum Signals { TIMEOUT_SIG, BUTTON_PRESSED_SIG, BUTTON_RELEASED_SIG, BLINKY_WORK_SIG, FORWARD_PRESSED_SIG, FORWARD_RELEASED_SIG, /* ... */ MAX_SIG /* the last signal */ }; typedef struct { SST_Evt super; /* inherit SST_Evt */ uint16_t toggles; /* number of toggles of the signal */ uint8_t ticks; /* number of clock ticks between */ } BlinkyWorkEvt; typedef struct { SST_Evt super; /* inherit SST_Evt */ uint16_t toggles; /* number of toggles of the signal */ } ButtonWorkEvt; void Blinky1_instantiate(void); extern SST_Task * const AO_Blinky1; /* opaque task pointer */ void Blinky3_instantiate(void); extern SST_Task * const AO_Blinky3; /* opaque task pointer */ void Button2a_instantiate(void); extern SST_Task * const AO_Button2a; /* opaque task pointer */ void Button2b_instantiate(void); extern SST_Task * const AO_Button2b; /* opaque task pointer */ #endif /* BLINKY_BUTTON_H_ */ ================================================ FILE: sst_c/examples/blinky_button.X/bsp.h ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #ifndef BSP_H_ #define BSP_H_ #define BSP_TICKS_PER_SEC 20U void BSP_init(void); void BSP_d1on(void); void BSP_d1off(void); void BSP_d2on(void); void BSP_d2off(void); void BSP_d3on(void); void BSP_d3off(void); void BSP_d4on(void); void BSP_d4off(void); void BSP_d5on(void); void BSP_d5off(void); void BSP_d6on(void); void BSP_d6off(void); /* immutable events for Blinky tasks */ SST_Evt const *BSP_getWorkEvtBlinky1(uint8_t num); SST_Evt const *BSP_getWorkEvtBlinky3(uint8_t num); #endif /* BSP_H_ */ ================================================ FILE: sst_c/examples/blinky_button.X/bsp_dspic33ep128gs804.c ================================================ /** * @file bsp_dspic33ep128gs804.c * @author ASHRAF (ashrafkamel491@gmail.com) * @version 1.0 * @date 2023-06-20 */ /*============================================================================ * Super-Simple Tasker (SST/C) Example for dsPIC33ep33ep128gs804 * * Q u a n t u m L e a P s * ------------------------ * Modern Embedded Software * * Copyright (C) 2005 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" #include "bsp.h" #include "blinky_button.h" #include "system_dspic33ep128gs804.h" /* dspic33ep drivers and register map*/ #include /* to exercise the FPU */ /* add other drivers if necessary... */ DBC_MODULE_NAME("bsp_dspic") /* for DBC assertions in this module */ /* Local-scope defines -----------------------------------------------------*/ /* test pins on GPIOA */ #define TST1_PORT GPIOA #define TST1_PIN PIN_4 /* LED Red */ #define TST2_PORT GPIOA #define TST2_PIN PIN_3 /* LED Blue */ /* test pins on GPIOD */ #define TST3_PORT GPIOB #define TST3_PIN PIN_11 #define TST4_PORT GPIOB #define TST4_PIN PIN_12 #define TST5_PORT GPIOB #define TST5_PIN PIN_13 /* test pins on GPIOA */ #define TST6_PORT GPIOB #define TST6_PIN PIN_14 /* LED Green */ /* Button on the board on GPIOF */ #define BTN_SW1_PORT GPIOC #define BTN_SW1 PIN_3 /* ISRs used in the application ============================================*/ void SysTick_Handler(void); /* prototype */ /* Timer1 ISR */ void __attribute__((__interrupt__, no_auto_psv)) _T1Interrupt(void) { IFS0bits.T1IF = 0; //Clear Timer1 interrupt flag SysTick_Handler(); } void SysTick_Handler(void) { /* system clock tick ISR */ BSP_d1on(); /* immutable timeout event */ static SST_Evt const tickEvt = { TIMEOUT_SIG }; SST_Task_post(AO_Blinky1, &tickEvt); /* every tick is fast for Blinky1 */ SST_Task_post(AO_Blinky3, &tickEvt); /* Perform the debouncing of buttons. The algorithm for debouncing * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle * and Michael Barr, page 71. */ static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = ~((BTN_SW1_PORT->PORT) & (BTN_SW1)); uint32_t tmp = buttons.depressed; /* save the debounced depressed */ buttons.depressed |= (buttons.previous & current); /* set depressed */ buttons.depressed &= (buttons.previous | current); /* clear released */ buttons.previous = current; /* update the history */ tmp ^= buttons.depressed; /* changed debounced depressed */ if ((tmp & BTN_SW1) != 0U) { /* debounced SW1 state changed? */ if ((buttons.depressed & BTN_SW1) != 0U) { /* is SW1 depressed? */ /* immutable button-press event */ static ButtonWorkEvt const pressEvt = { .super.sig = BUTTON_PRESSED_SIG, .toggles = 60U }; /* immutable forward-press event */ static ButtonWorkEvt const fPressEvt = { .super.sig = FORWARD_PRESSED_SIG, .toggles = 60U }; SST_Task_post(AO_Button2a, &fPressEvt.super); SST_Task_post(AO_Button2a, &pressEvt.super); } else { /* B1 is released */ /* immutable button-release event */ static ButtonWorkEvt const releaseEvt = { .super.sig = BUTTON_RELEASED_SIG, .toggles = 80U }; /* immutable forward-release event */ static ButtonWorkEvt const fReleaseEvt = { .super.sig = FORWARD_RELEASED_SIG, .toggles = 80U }; SST_Task_post(AO_Button2a, &fReleaseEvt.super); SST_Task_post(AO_Button2a, &releaseEvt.super); } } BSP_d1off(); } /* Assertion handler ======================================================*/ DBC_NORETURN void DBC_fault_handler(char const * const module, int const label) { /* * NOTE: add here your application-specific error handling */ (void)module; (void)label; /* set PRIMASK to disable interrupts and stop SST right here */ SST_PORT_CRIT_ENTRY(); #ifndef NDEBUG for (;;) { /* keep blinking LED2 */ BSP_d6on(); /* turn LED2 on */ uint32_t volatile ctr; for (ctr = 1000000U; ctr > 0U; --ctr) { } BSP_d6off(); /* turn LED2 off */ for (ctr = 1000000U; ctr > 0U; --ctr) { } } #endif dspic_SystemReset(); } /*..........................................................................*/ void assert_failed(char const * const module, int const label);/* prototype */ void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } /* SST task activations ====================================================*/ /* repurpose regular IRQs for SST Tasks */ void __attribute__((__interrupt__, no_auto_psv)) _PTG0Interrupt(void) { IFS9bits.PTG0IF = 0; SST_Task_activate(AO_Blinky3); } void __attribute__((__interrupt__, no_auto_psv)) _PTG1Interrupt(void) { IFS9bits.PTG1IF = 0; SST_Task_activate(AO_Button2b); } void __attribute__((__interrupt__, no_auto_psv)) _PTG2Interrupt(void) { IFS9bits.PTG2IF = 0; SST_Task_activate(AO_Button2a); } void __attribute__((__interrupt__, no_auto_psv)) _PTG3Interrupt(void) { IFS9bits.PTG3IF = 0; SST_Task_activate(AO_Blinky1); } /* BSP functions ===========================================================*/ void BSP_init(void) { /* assign IRQs to tasks. NOTE: critical for SST... */ SST_Task_setIRQ(AO_Blinky3, _PTG0Interrupt_n); SST_Task_setIRQ(AO_Button2b, _PTG1Interrupt_n); SST_Task_setIRQ(AO_Button2a, _PTG2Interrupt_n); SST_Task_setIRQ(AO_Blinky1, _PTG3Interrupt_n); gpio_set_direction(TST1_PORT, TST1_PIN, GPIO_OUTPUT); gpio_set_direction(TST2_PORT, TST2_PIN, GPIO_OUTPUT); gpio_set_direction(TST3_PORT, TST3_PIN, GPIO_OUTPUT); gpio_set_direction(TST4_PORT, TST4_PIN, GPIO_OUTPUT); gpio_set_direction(TST5_PORT, TST5_PIN, GPIO_OUTPUT); gpio_set_direction(TST6_PORT, TST6_PIN, GPIO_OUTPUT); gpio_set_direction(BTN_SW1_PORT, BTN_SW1, GPIO_INPUT_PU); } /*..........................................................................*/ static void exerciseFPU(float x) { /* exercise the single-precision FPU by calculating the identity: * sqrt(x) == x / sqrt(x) for x > 0 */ float tmp1 = sqrtf(x); /* single-precision sqrt() */ float tmp2 = x / tmp1; DBC_ENSURE(200, (tmp1 - 1e-4f <= tmp2) && (tmp2 <= tmp1 + 1e-4f)); } /*..........................................................................*/ void BSP_d1on(void) { /* LED-Red */ gpio_set_level(TST1_PORT ,TST1_PIN, 1); /* don't use the FPU in the ISR */ } void BSP_d1off(void) { gpio_set_level(TST1_PORT ,TST1_PIN, 0); } /*..........................................................................*/ void BSP_d2on(void) { /* LED-Blue */ gpio_set_level(TST2_PORT ,TST2_PIN, 1); exerciseFPU(1.2345f); } void BSP_d2off(void) { gpio_set_level(TST2_PORT ,TST2_PIN, 0); } /*..........................................................................*/ void BSP_d3on(void) { gpio_set_level(TST3_PORT ,TST3_PIN, 1); exerciseFPU(0.345f); } void BSP_d3off(void) { gpio_set_level(TST3_PORT ,TST3_PIN, 0); } /*..........................................................................*/ void BSP_d4on(void) { gpio_set_level(TST4_PORT ,TST4_PIN, 1); exerciseFPU(0.456f); } void BSP_d4off(void) { gpio_set_level(TST4_PORT ,TST4_PIN, 0); } /*..........................................................................*/ void BSP_d5on(void) { gpio_set_level(TST5_PORT ,TST5_PIN, 1); exerciseFPU(1.567f); } void BSP_d5off(void) { gpio_set_level(TST5_PORT ,TST5_PIN, 0); } /*..........................................................................*/ void BSP_d6on(void) { /* LED2-Green */ gpio_set_level(TST6_PORT ,TST6_PIN, 1); exerciseFPU(1.2345f); } void BSP_d6off(void) { gpio_set_level(TST6_PORT ,TST6_PIN, 0); } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky1(uint8_t num) { /* immutable work events for Blinky1 */ static BlinkyWorkEvt const workBlinky1[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 40U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 30U, .ticks = 7U, } }; DBC_REQUIRE(500, num < ARRAY_NELEM(workBlinky1)); /* must be in range */ return &workBlinky1[num].super; } /*..........................................................................*/ SST_Evt const *BSP_getWorkEvtBlinky3(uint8_t num) { /* immutable work events for Blinky3 */ static BlinkyWorkEvt const workBlinky3[] = { { .super.sig = BLINKY_WORK_SIG, .toggles = 20U, .ticks = 5U, }, { .super.sig = BLINKY_WORK_SIG, .toggles = 10U, .ticks = 3U, } }; DBC_REQUIRE(600, num < ARRAY_NELEM(workBlinky3)); /* must be in range */ return &workBlinky3[num].super; } /* SST callbacks ===========================================================*/ void SST_onStart(void) { SystemCoreClockUpdate(); /* set up the SysTick timer "timer1" to fire at BSP_TICKS_PER_SEC rate */ volatile uint16_t temp = BSP_TICKS_PER_SEC; SysTick_Config(temp); /* set priorities of ISRs used in the system */ interrupt_SetPriority(_T1Interrupt_n, 7U); // tick timer highest priority /* ... */ } /*..........................................................................*/ void SST_onIdle(void) { BSP_d6on(); /* turn LED-Green on */ #ifdef NDEBUG /* Put the CPU and peripherals to the low-power mode. * you might need to customize the clock management for your application, * see the datasheet for your particular MCU. */ BSP_d6off(); /* turn LED-Green off */ Idle(); /* Wait-For-Interrupt */ BSP_d6on(); /* turn LED-Green on */ #endif BSP_d6off(); /* turn LED-Green off */ } ================================================ FILE: sst_c/examples/blinky_button.X/button2a.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky_button.h" /* application shared interface */ DBC_MODULE_NAME("button2a") /* for DBC assertions in this module */ /*..........................................................................*/ typedef struct { /* Button2a task */ SST_Task super; /* inherit SST_Task */ /* add internal variables for this AO... */ } Button2a; static void Button2a_ctor(Button2a * const me); static void Button2a_init(Button2a * const me, SST_Evt const * const ie); static void Button2a_dispatch(Button2a * const me, SST_Evt const * const e); /*..........................................................................*/ static Button2a Button2a_inst; /* the Button2a instance */ SST_Task * const AO_Button2a = &Button2a_inst.super; /* opaque AO pointer */ void Button2a_instantiate(void) { Button2a_ctor(&Button2a_inst); } /*..........................................................................*/ static void Button2a_ctor(Button2a * const me) { SST_Task_ctor( &me->super, (SST_Handler)&Button2a_init, (SST_Handler)&Button2a_dispatch); } /*..........................................................................*/ static void Button2a_init(Button2a * const me, SST_Evt const * const ie) { (void)me; (void)ie; } /*..........................................................................*/ static void Button2a_dispatch(Button2a * const me, SST_Evt const * const e) { (void)me; switch (e->sig) { case BUTTON_PRESSED_SIG: { BSP_d4on(); /* Button2a --> Blinky1 */ SST_Task_post(AO_Blinky1, BSP_getWorkEvtBlinky1(1U)); BSP_d4off(); for (uint16_t i = SST_EVT_DOWNCAST(ButtonWorkEvt, e)->toggles; i > 0U; --i) { BSP_d4on(); BSP_d4off(); } break; } case FORWARD_PRESSED_SIG: { BSP_d4on(); /* immutable event can be forwarded to another Task */ SST_Task_post(AO_Button2b, e); /* Button2a --> Button2b */ BSP_d4off(); break; } case BUTTON_RELEASED_SIG: { BSP_d4on(); /* Button2a --> Blinky1 */ SST_Task_post(AO_Blinky1, BSP_getWorkEvtBlinky1(0U)); BSP_d4off(); for (uint16_t i = SST_EVT_DOWNCAST(ButtonWorkEvt, e)->toggles; i > 0U; --i) { BSP_d4on(); BSP_d4off(); } break; } case FORWARD_RELEASED_SIG: { BSP_d4on(); /* immutable event can be forwarded to another Task */ SST_Task_post(AO_Button2b, e); /* Button2a --> Button2b */ BSP_d4off(); break; } default: { DBC_ERROR(500); /* unexpected event */ break; } } } ================================================ FILE: sst_c/examples/blinky_button.X/button2b.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky_button.h" /* application shared interface */ DBC_MODULE_NAME("button2b") /* for DBC assertions in this module */ /*..........................................................................*/ typedef struct { /* Button2b task */ SST_Task super; /* inherit SST_Task */ /* add internal variables for this AO... */ } Button2b; static void Button2b_ctor(Button2b * const me); static void Button2b_init(Button2b * const me, SST_Evt const * const e); static void Button2b_dispatch(Button2b * const me, SST_Evt const * const e); /*..........................................................................*/ static Button2b Button2b_inst; /* the Button2b instance */ SST_Task * const AO_Button2b = &Button2b_inst.super; /* opaque AO pointer */ void Button2b_instantiate(void) { Button2b_ctor(&Button2b_inst); } /*..........................................................................*/ static void Button2b_ctor(Button2b * const me) { SST_Task_ctor( &me->super, (SST_Handler)&Button2b_init, (SST_Handler)&Button2b_dispatch); } /*..........................................................................*/ static void Button2b_init(Button2b * const me, SST_Evt const * const ie) { (void)me; (void)ie; } /*..........................................................................*/ static void Button2b_dispatch(Button2b * const me, SST_Evt const * const e) { switch (e->sig) { case FORWARD_PRESSED_SIG: { BSP_d3on(); /* Button2b --> Blinky3 */ SST_Task_post(AO_Blinky3, BSP_getWorkEvtBlinky3(1U)); BSP_d3off(); for (uint16_t i = SST_EVT_DOWNCAST(ButtonWorkEvt, e)->toggles; i > 0U; --i) { BSP_d3on(); BSP_d3off(); } break; } case FORWARD_RELEASED_SIG: { BSP_d3on(); /* Button2b --> Blinky3 */ SST_Task_post(AO_Blinky3, BSP_getWorkEvtBlinky3(0U)); BSP_d3off(); for (uint16_t i = SST_EVT_DOWNCAST(ButtonWorkEvt, e)->toggles; i > 0U; --i) { BSP_d3on(); BSP_d3off(); } break; } default: { DBC_ERROR(500); /* unexpected event */ break; } } } ================================================ FILE: sst_c/examples/blinky_button.X/configuration_bits.h ================================================ /* * File: configuration_bits.h * Author: AMASOU02 * * Created on June 19, 2023, 7:13 AM */ #ifndef CONFIGURATION_BITS_H #define CONFIGURATION_BITS_H #ifdef __cplusplus extern "C" { #endif // DSPIC33EP128GS804 Configuration Bit Settings // 'C' source line config statements // FSEC #pragma config BWRP = OFF // Boot Segment Write-Protect bit (Boot Segment may be written) #pragma config BSS = DISABLED // Boot Segment Code-Protect Level bits (No Protection (other than BWRP)) #pragma config BSEN = OFF // Boot Segment Control bit (No Boot Segment) #pragma config GWRP = OFF // General Segment Write-Protect bit (General Segment may be written) #pragma config GSS = DISABLED // General Segment Code-Protect Level bits (No Protection (other than GWRP)) #pragma config CWRP = OFF // Configuration Segment Write-Protect bit (Configuration Segment may be written) #pragma config CSS = DISABLED // Configuration Segment Code-Protect Level bits (No Protection (other than CWRP)) #pragma config AIVTDIS = OFF // Alternate Interrupt Vector Table bit (Disabled AIVT) // FBSLIM #pragma config BSLIM = 0x1FFF // Boot Segment Flash Page Address Limit bits (Enter Hexadecimal value) // FSIGN // FOSCSEL #pragma config FNOSC = FRC // Oscillator Source Selection (Internal Fast RC (FRC)) #pragma config IESO = OFF // Two-speed Oscillator Start-up Enable bit (Start up with user-selected oscillator source) // FOSC #pragma config POSCMD = NONE // Primary Oscillator Mode Select bits (Primary Oscillator disabled) #pragma config OSCIOFNC = ON // OSC2 Pin Function bit (OSC2 is general purpose digital I/O pin) #pragma config IOL1WAY = ON // Peripheral pin select configuration bit (Allow only one reconfiguration) #pragma config FCKSM = CSDCMD // Clock Switching Mode bits (Both Clock switching and Fail-safe Clock Monitor are disabled) #pragma config PLLKEN = ON // PLL Lock Enable Bit (Clock switch to PLL source will wait until the PLL lock signal is valid) // FWDT #pragma config WDTPOST = PS32768 // Watchdog Timer Postscaler bits (1:32,768) #pragma config WDTPRE = PR128 // Watchdog Timer Prescaler bit (1:128) #pragma config WDTEN = OFF // Watchdog Timer Enable bits (WDT and SWDTEN disabled) #pragma config WINDIS = OFF // Watchdog Timer Window Enable bit (Watchdog Timer in Non-Window mode) #pragma config WDTWIN = WIN25 // Watchdog Timer Window Select bits (WDT Window is 25% of WDT period) // FPOR // FICD #pragma config ICS = PGD1 // ICD Communication Channel Select bits (Communicate on PGEC1 and PGED1) #pragma config JTAGEN = OFF // JTAG Enable bit (JTAG is disabled) #pragma config BTSWP = OFF // BOOTSWP Instruction Enable/Disable bit (BOOTSWP instruction is disabled) // FDEVOPT #pragma config PWMLOCK = ON // PWMx Lock Enable bit (Certain PWM registers may only be written after key sequency) #pragma config ALTI2C1 = OFF // Alternate I2C1 Pin bit (I2C1 mapped to SDA1/SCL1 pins) #pragma config ALTI2C2 = OFF // Alternate I2C2 Pin bit (I2C2 mapped to SDA2/SCL2 pins) #pragma config DBCC = OFF // DACx Output Cross Connection bit (No Cross Connection between DAC outputs) // FALTREG #pragma config CTXT1 = OFF // Specifies Interrupt Priority Level (IPL) Associated to Alternate Working Register 1 bits (Not Assigned) #pragma config CTXT2 = OFF // Specifies Interrupt Priority Level (IPL) Associated to Alternate Working Register 2 bits (Not Assigned) #pragma config CTXT3 = OFF // Specifies Interrupt Priority Level (IPL) Associated to Alternate Working Register 2 bits (Not Assigned) #pragma config CTXT4 = OFF // Specifies Interrupt Priority Level (IPL) Associated to Alternate Working Register 2 bits (Not Assigned) // FBTSEQ #pragma config BSEQ = 0xFFF // Relative value defining which partition will be active after device Reset; the partition containing a lower boot number will be active (Enter Hexadecimal value) #pragma config IBSEQ = 0xFFF // The one's complement of BSEQ; must be calculated by the user and written during device programming. (Enter Hexadecimal value) // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF. #include #ifdef __cplusplus } #endif #endif /* CONFIGURATION_BITS_H */ ================================================ FILE: sst_c/examples/blinky_button.X/main.c ================================================ /*============================================================================ * Super-Simple Tasker (SST/C) Example * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ============================================================================*/ #include "configuration_bits.h" #include "sst.h" /* SST framework */ #include "bsp.h" /* Board Support Package interface */ #include "blinky_button.h" /* application shared interface */ /*..........................................................................*/ int main() { SST_init(); /* initialize the SST kernel */ BSP_init(); /* initialize the Board Support Package */ /* instantiate and start all SST tasks... */ Blinky1_instantiate(); static SST_Evt const *blinky1QSto[10]; /* Event queue storage */ SST_Task_start( AO_Blinky1, /* AO pointer to start */ 1U, /* SST-priority */ blinky1QSto, /* storage for the AO's queue */ ARRAY_NELEM(blinky1QSto), /* queue length */ BSP_getWorkEvtBlinky1(0U)); /* initialization event */ Button2a_instantiate(); static SST_Evt const *button2aQSto[8]; /* Event queue storage */ SST_Task_start( AO_Button2a, /* AO pointer to start */ 2U, /* SST-priority */ button2aQSto, /* storage for the AO's queue */ ARRAY_NELEM(button2aQSto), /* queue length */ (SST_Evt const *)0); /* initialization event -- not used */ Button2b_instantiate(); static SST_Evt const *button2bQSto[6]; /* Event queue storage */ SST_Task_start( AO_Button2b, /* AO pointer to start */ 2U, /* SST-priority */ button2bQSto, /* storage for the AO's queue */ ARRAY_NELEM(button2bQSto), /* queue length */ (SST_Evt const *)0); /* initialization event -- not used */ Blinky3_instantiate(); static SST_Evt const *blinky3QSto[4]; /* Event queue storage */ SST_Task_start( AO_Blinky3, /* AO pointer to start */ 3U, /* SST-priority */ blinky3QSto, /* storage for the AO's queue */ ARRAY_NELEM(blinky3QSto), /* queue length */ BSP_getWorkEvtBlinky3(0U)); /* initialization event */ return SST_Task_run(); /* run the SST tasks */ /* NOTE; in embedded systems SST_Task_run() should not return */ } ================================================ FILE: sst_c/examples/blinky_button.X/nbproject/configurations.xml ================================================ blinky_button.h bsp.h configuration_bits.h blinky1.c blinky3.c bsp_dspic33ep128gs804.c button2a.c button2b.c ../../../include/dbc_assert.h ../../../include/sst.h ../../ports/dspic/sst_port.c ../../ports/dspic/sst_port.h ../../src/sst.c Makefile main.c system_dspic33ep128gs804.c system_dspic33ep128gs804.h D:\projs\blinky_button.X D:\projs\Super-Simple-Tasker\include D:\projs\Super-Simple-Tasker\sst_c\src D:\projs\Super-Simple-Tasker\sst_c\ports\dspic ../../src ../../ports/dspic ../../../include . Makefile localhost dsPIC33EP128GS804 PICkit3PlatformTool XC16 2.10 3 false false false false false false false false ================================================ FILE: sst_c/examples/blinky_button.X/nbproject/project.xml ================================================ com.microchip.mplab.nbide.embedded.makeproject blinky_button cafad642-ac00-400f-b645-1e39503e8bdc 0 ISO-8859-1 D:\projs\blinky_button.X D:\projs\Super-Simple-Tasker\include D:\projs\Super-Simple-Tasker\sst_c\src D:\projs\Super-Simple-Tasker\sst_c\ports\dspic ../../src ../../ports/dspic ../../../include . default 2 false ================================================ FILE: sst_c/examples/blinky_button.X/system_dspic33ep128gs804.c ================================================ /** * @file system_dspic33ep128gs804.c * @author ASHRAF (ashrafkamel491@gmail.com) * @version 1 */ #include "system_dspic33ep128gs804.h" #include "xc.h" /** * Sets the output of a GPIO pin . * @param[in] GPIOx: where x can be (A,B,C) to select the GPIO peripheral. * @param pin_no: The port pin to be set to a certain output level. * This parameter can be one of PIN_X where x can be (0..15) or ALL. * @param level: the new output state of the pin */ void gpio_set_level(gpio_t gpio, gpio_pin_t pin_num, int8_t state) { if (state) gpio->PORT |= pin_num; else gpio->PORT &= ~pin_num; } /** * Gets the input of a GPIO pin . * @param[in] GPIOx: where x can be (A,B,C) to select the GPIO peripheral. * @param pin_no: The port pin to be read. * This parameter can be one of PIN_X where x can be (0..15) or ALL. * @return -HIGH 1 * -LOW 0 */ int8_t gpio_get_level(gpio_t gpio,gpio_pin_t pin_num) { return (gpio->PORT & pin_num) ? HIGH : LOW; } /** * Sets the direction of a specific pin * @param[in] GPIOx: where x can be (A,B,C) to select the GPIO peripheral. * @param pin: The port pin to be assigned a direction. * This parameter can be one of PIN_X where x can be (0..15) or ALL. * @param direction: is the new direction of the pin * * \b Example: * @code * gpio_set_direction(GPIOA, PIN_8, GPIO_INPUT_PU); * @endcode */ void gpio_set_direction(gpio_t GPIOx, gpio_pin_t pin_no, gpio_direction_t direction) { if(direction == GPIO_INPUT_AN) { GPIOx->TRIS |= pin_no; //set direction input GPIOx->CNEN &= ~pin_no; //disable change int GPIOx->CNPU &= ~pin_no; //disable pull up GPIOx->CNPD &= ~pin_no; //disable pull down GPIOx->ANSEL |= pin_no; } else if (direction == GPIO_OPEN_DRAIN) { GPIOx->ODC |= pin_no; GPIOx->ANSEL &= ~pin_no; } else { GPIOx->ODC &= ~pin_no; GPIOx->ANSEL &= ~pin_no; if (direction == GPIO_OUTPUT) { GPIOx->CNEN &= ~pin_no; //disable change int GPIOx->CNPU &= ~pin_no; //disable pull up GPIOx->CNPD &= ~pin_no; //disable pull down GPIOx->TRIS &= ~pin_no; //set direction output } else { GPIOx->TRIS |= pin_no; //set direction input if (direction == (GPIO_INPUT_PU)) { GPIOx->CNPD &= ~pin_no; GPIOx->CNPU |= pin_no; } else if (direction == (GPIO_INPUT_PD)) { GPIOx->CNPU &= ~pin_no; GPIOx->CNPD |= pin_no; } } } } #define F_CPU_MHZ 7.37F void SysTick_Config(uint16_t Freq_hz) { float period_us = 1.0/(float)Freq_hz; period_us *= 1000; period_us *= 1000; T1CONbits.TON = 0; // Disable Timer T1CONbits.TCS = 0; // Select internal instruction cycle clock T1CONbits.TGATE = 0; // Disable Gated Timer mode T1CONbits.TCKPS = 0b01; // Select 1:8 Prescaler TMR1 = 0x00; // Clear timer register volatile uint16_t temp = F_CPU_MHZ * period_us / 16; // Load the period value PR1 = temp; IFS0bits.T1IF = 0; // Clear Timer 1 Interrupt Flag IEC0bits.T1IE = 1; // Enable Timer1 interrupt T1CONbits.TON = 1; // Start Timer } void SystemCoreClockUpdate(void) { /*doze divider configure*/ CLKDIVbits.DOZE = 0b010; // use default internal Fast RC oscillator // 7.37 MHz } void dspic_SystemReset(void) { __builtin_software_breakpoint(); } #define IFS_BASE ((uint16_t volatile *)0x800U) //interrupt flag Status (pend) #define IEC_BASE ((uint16_t volatile *)0x820U) //interrupt enable control #define IPC_BASE ((uint16_t volatile *)0x840U) //interrupt priority control void interrupt_SetPriority(IRQn_Type IRQn, uint8_t priority) { //CLR IPC_BASE[IRQn/4] &= ~(0X7<< ((IRQn%4)*4)); //SET IPC_BASE[IRQn/4] |= priority << ((IRQn%4)*4); } void interrupt_Enable(IRQn_Type IRQn) { IEC_BASE[IRQn/16] |= 1 << (IRQn%16); } ================================================ FILE: sst_c/examples/blinky_button.X/system_dspic33ep128gs804.h ================================================ /* * File: drivers.h * Author: ASHRAF * * Created on June 12, 2023, 3:17 PM */ #ifndef DRIVERS_H #define DRIVERS_H #ifdef __cplusplus extern "C" { #endif #include #include "xc.h" /* the device specific header */ /********* GPIO REGISTERS ********/ typedef volatile struct { // GPIO Structure uint16_t TRIS; uint16_t PORT; uint16_t LAT; uint16_t ODC; uint16_t CNEN; uint16_t CNPU; uint16_t CNPD; uint16_t ANSEL; } *const gpio_t; #define GPIOA_BASE 0xE00 #define GPIOB_BASE 0xE10 #define GPIOC_BASE 0xE20 #define GPIO_CHANGE_BASE 0xE08 typedef enum { _INT0Interrupt_n = 0, _IC1Interrupt_n = 1, _OC1Interrupt_n = 2, _T1Interrupt_n = 3, _DMA0Interrupt_n = 4, _IC2Interrupt_n = 5, _OC2Interrupt_n = 6, _T2Interrupt_n = 7, _T3Interrupt_n = 8, _SPI1TXInterrupt_n = 9, _SPI1RXInterrupt_n = 10, _U1RXInterrupt_n = 11, _U1TXInterrupt_n = 12, _AD1Interrupt_n = 13, _DMA1Interrupt_n = 14, _NVMInterrupt_n = 15, _SI2C1Interrupt_n = 16, _MI2C1Interrupt_n = 17, _CMP1Interrupt_n = 18, _CNInterrupt_n = 19, _INT1Interrupt_n = 20, _DMA2Interrupt_n = 24, _OC3Interrupt_n = 25, _OC4Interrupt_n = 26, _T4Interrupt_n = 27, _T5Interrupt_n = 28, _INT2Interrupt_n = 29, _U2RXInterrupt_n = 30, _U2TXInterrupt_n = 31, _SPI2TXInterrupt_n = 32, _SPI2RXInterrupt_n = 33, _C1RxInterrupt_n = 34, _C1Interrupt_n = 35, _DMA3Interrupt_n = 36, _IC3Interrupt_n = 37, _IC4Interrupt_n = 38, _SI2C2Interrupt_n = 49, _MI2C2Interrupt_n = 50, _INT4Interrupt_n = 54, _C2RxInterrupt_n = 55, _C2Interrupt_n = 56, _PWMSpEventMatchInterrupt_n = 57, _U1ErrInterrupt_n = 65, _U2ErrInterrupt_n = 66, _C1TxInterrupt_n = 70, _C2TxInterrupt_n = 71, _PWMSecSpEventMatchInterrupt_n = 73, _SPI3TXInterrupt_n = 90, _SPI3RXInterrupt_n = 91, _PWM1Interrupt_n = 94, _PWM2Interrupt_n = 95, _PWM3Interrupt_n = 96, _PWM4Interrupt_n = 97, _PWM5Interrupt_n = 98, _PWM6Interrupt_n = 99, _PWM7Interrupt_n = 100, _PWM8Interrupt_n = 101, _CMP2Interrupt_n = 103, _CMP3Interrupt_n = 104, _CMP4Interrupt_n = 105, _ADCAN0Interrupt_n = 110, _ADCAN1Interrupt_n = 111, _ADCAN2Interrupt_n = 112, _ADCAN3Interrupt_n = 113, _ADCAN4Interrupt_n = 114, _ADCAN5Interrupt_n = 115, _ADCAN6Interrupt_n = 116, _ADCAN7Interrupt_n = 117, _SPI1GInterrupt_n = 124, _SPI2GInterrupt_n = 125, _SPI3GInterrupt_n = 126, _CLC1Interrupt_n = 138, _CLC2Interrupt_n = 139, _CLC3Interrupt_n = 140, _CLC4Interrupt_n = 141, _ICDInterrupt_n = 142, _JTAGInterrupt_n = 143, _PTGStepInterrupt_n = 145, _PTGWDTInterrupt_n = 146, _PTG0Interrupt_n = 147, _PTG1Interrupt_n = 148, _PTG2Interrupt_n = 149, _PTG3Interrupt_n = 150, _ADCAN8Interrupt_n = 151, _ADCAN9Interrupt_n = 152, _ADCAN10Interrupt_n = 153, _ADCAN11Interrupt_n = 154, _ADCAN12Interrupt_n = 155, _ADCAN13Interrupt_n = 156, _ADCAN14Interrupt_n = 157, _ADCAN15Interrupt_n = 158, _ADCAN16Interrupt_n = 159, _ADCAN17Interrupt_n = 160, _ADCAN18Interrupt_n = 161, _ADCAN19Interrupt_n = 162, _ADCAN20Interrupt_n = 163, _ADCAN21Interrupt_n = 164, _I2C1BCInterrupt_n = 173, _I2C2BCInterrupt_n = 174, _ADCMP0Interrupt_n = 177, _ADCMP1Interrupt_n = 178, _ADFLTR0Interrupt_n = 179, _ADFLTR1Interrupt_n = 180, _ADCCore0Interrupt_n = 187, _ADCCore1Interrupt_n = 188, _ADCCore2Interrupt_n = 189, _ADCCore3Interrupt_n = 190 }IRQn_Type; #define GPIOA ((gpio_t)GPIOA_BASE) #define GPIOB ((gpio_t)GPIOB_BASE) #define GPIOC ((gpio_t)GPIOC_BASE) typedef uint16_t gpio_pin_t; #define PIN_0 0x0001 //0b0000 0000 0000 0001 #define PIN_1 0x0002 //0b0000 0000 0000 0010 #define PIN_2 0x0004 //0b0000 0000 0000 0100 #define PIN_3 0x0008 //0b0000 0000 0000 1000 #define PIN_4 0x0010 //0b0000 0000 0001 0000 #define PIN_5 0x0020 //0b0000 0000 0010 0000 #define PIN_6 0x0040 //0b0000 0000 0100 0000 #define PIN_7 0x0080 //0b0000 0000 1000 0000 #define PIN_8 0x0100 //0b0000 0001 0000 0000 #define PIN_9 0x0200 //0b0000 0010 0000 0000 #define PIN_10 0x0400 //0b0000 0100 0000 0000 #define PIN_11 0x0800 //0b0000 1000 0000 0000 #define PIN_12 0x1000 //0b0001 0000 0000 0000 #define PIN_13 0x2000 //0b0010 0000 0000 0000 #define PIN_14 0x4000 //0b0100 0000 0000 0000 #define PIN_15 0x8000 //0b1000 0000 0000 0000 #define PIN_ALL 0xffff //0b1111 1111 1111 1111 #define HIGH 1 #define LOW 0 typedef uint8_t gpio_direction_t; #define GPIO_INPUT 0 // #define GPIO_OUTPUT 1 // #define GPIO_INPUT_PU 2 // Pull Up #define GPIO_INPUT_PD 3 // Pull Down #define GPIO_OPEN_DRAIN 4 // #define GPIO_INPUT_AN 5 // typedef uint8_t gpio_level_t; void gpio_set_direction (gpio_t GPIOx, gpio_pin_t pin_no, gpio_direction_t direction); void gpio_set_level(gpio_t gpio, gpio_pin_t pin_num, int8_t state); int8_t gpio_get_level(gpio_t gpio, gpio_pin_t pin_num); void dspic_SystemReset(void); void SystemCoreClockUpdate(void); void interrupt_SetPriority(IRQn_Type IRQn, uint8_t priority); void interrupt_Enable(IRQn_Type IRQn); void SysTick_Config(uint16_t freq_hz); #ifdef __cplusplus } #endif #endif /* DRIVERS_H */ ================================================ FILE: sst_c/ports/arm-cm/sst_port.c ================================================ /*=========================================================================== * Super-Simple Tasker (SST/C) port to ARM Cortex-M * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ===========================================================================*/ #include "sst.h" /* Super-Simple Tasker (SST/C) */ #include "dbc_assert.h" /* Design By Contract (DBC) assertions */ DBC_MODULE_NAME("sst_port") /* for DBC assertions in this module */ #define NVIC_PEND ((uint32_t volatile *)0xE000E200U) #define NVIC_EN ((uint32_t volatile *)0xE000E100U) #define NVIC_IP ((uint32_t volatile *)0xE000E400U) #define SCB_SYSPRI ((uint32_t volatile *)0xE000ED14U) #define SCB_AIRCR *((uint32_t volatile *)0xE000ED0CU) #define FPU_FPCCR *((uint32_t volatile *)0xE000EF34U) /*..........................................................................*/ /* # of unused interrupt priority bits in NVIC */ static uint32_t nvic_prio_shift; /* SST kernel facilities ---------------------------------------------------*/ void SST_init(void) { /* determine number of NVIC priority bits by writing 0xFF to the * NIVIC IP register for PendSV and then reading back the result, * which has only the implemented bits set. */ uint32_t tmp = SCB_SYSPRI[3]; SCB_SYSPRI[3] |= (0xFFU << 16U); /* write 0xFF to PendSV prio */ uint32_t prio = ((SCB_SYSPRI[3] >> 16U) & 0xFFU); /* read back */ SCB_SYSPRI[3] = tmp; /* restore the original PendSV prio */ for (tmp = 0U; tmp < 8U; ++tmp) { if ((prio & (1U << tmp)) != 0U) { break; } } nvic_prio_shift = tmp; #if (__ARM_FP != 0) /* configure the FPU for SST */ FPU_FPCCR |= (1U << 30U) /* automatic FPU state preservation (ASPEN) */ | (1U << 31U); /* lazy stacking (LSPEN) */ #endif } /*..........................................................................*/ void SST_start(void) { /* Set the NVIC priority grouping to default 0 * * NOTE: * Typically the SST port to ARM Cortex-M should waste no NVIC priority * bits for grouping. This code ensures this setting, but priority * grouping can be still overridden in the application-specific * callback SST_onStart(). */ uint32_t tmp = SCB_AIRCR; /* clear the key bits 31:16 and priority grouping bits 10:8 */ tmp &= ~((0xFFFFU << 16U) | (0x7U << 8U)); SCB_AIRCR = (0x05FAU << 16U) | tmp; } /* SST Task facilities -----------------------------------------------------*/ void SST_Task_setPrio(SST_Task * const me, SST_TaskPrio prio) { /*! @pre * - the IRQ number must be already set * - the priority must fit in the NVIC */ DBC_REQUIRE(200, (me->nvic_irq != 0U) && (prio <= (0xFFU >> nvic_prio_shift))); /* convert the SST direct priority (1,2,..) to NVIC priority... */ uint32_t nvic_prio = ((0xFFU >> nvic_prio_shift) + 1U - prio) << nvic_prio_shift; SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); /* set the Task priority of the associated IRQ */ uint32_t tmp = NVIC_IP[me->nvic_irq >> 2U]; tmp &= ~(0xFFU << ((me->nvic_irq & 3U) << 3U)); tmp |= (nvic_prio << ((me->nvic_irq & 3U) << 3U)); NVIC_IP[me->nvic_irq >> 2U] = tmp; /* enable the IRQ associated with the Task */ NVIC_EN[me->nvic_irq >> 5U] = (1U << (me->nvic_irq & 0x1FU)); SST_PORT_CRIT_EXIT(); /* store the address of NVIC_PEND address and the IRQ bit */ me->nvic_pend = &NVIC_PEND[me->nvic_irq >> 5U]; me->nvic_irq = (1U << (me->nvic_irq & 0x1FU)); } /*..........................................................................*/ void SST_Task_activate(SST_Task * const me) { /*! @pre the queue must have some events */ DBC_REQUIRE(300, me->nUsed > 0U); /* get the event out of the queue */ /* NOTE: no critical section because me->tail is accessed only * from this task */ SST_Evt const *e = me->qBuf[me->tail]; if (me->tail == 0U) { /* need to wrap the tail? */ me->tail = me->end; /* wrap around */ } else { --me->tail; } SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); if ((--me->nUsed) > 0U) { /* some events still present in the queue? */ *me->nvic_pend = me->nvic_irq; /* <=== pend the associated IRQ */ } SST_PORT_CRIT_EXIT(); /* dispatch the received event to this task */ (*me->dispatch)(me, e); /* NOTE: virtual call */ /* TBD: implement event recycling */ } /*..........................................................................*/ void SST_Task_setIRQ(SST_Task * const me, uint8_t irq) { me->nvic_irq = irq; } /*..........................................................................*/ SST_LockKey SST_Task_lock(SST_TaskPrio ceiling) { #if (__ARM_ARCH == 6) /* ARMv6-M? */ /* NOTE: * ARMv6-M (Cortex-M0/M0+/M1) do NOT support the BASEPRI register * and simple selective scheduler locking is not possible. * Instead, on this architectures, SST scheduler lock can be * implemented by temporarily raising the current task priority * to the ceiling level. */ /* TBD... */ (void)ceiling; /* unused param for now */ return 0U; #else /* ARMv7-M+ */ /* NOTE: * ARMv7-M+ support the BASEPRI register and the selective SST scheduler * locking is implemented by setting BASEPRI to the ceiling level. */ uint32_t nvic_prio = ((0xFFU >> nvic_prio_shift) + 1U - ceiling) << nvic_prio_shift; SST_LockKey basepri_; /* initialized in the following asm() instruction */ __asm volatile ("mrs %0,BASEPRI" : "=r" (basepri_) :: ); if (basepri_ > nvic_prio) { /* current priority lower than the ceiling? */ __asm volatile ("cpsid i\n msr BASEPRI,%0\n cpsie i" :: "r" (nvic_prio) : ); } return basepri_; #endif } /*..........................................................................*/ void SST_Task_unlock(SST_LockKey lock_key) { #if (__ARM_ARCH == 6) /* ARMv6-M? */ /* TBD... */ (void)lock_key; /* unused param for now */ #else /* ARMv7-M+ */ /* NOTE: * ARMv7-M+ support the BASEPRI register and the selective SST scheduler * unlocking is implemented by restoring BASEPRI to the lock_key level. */ __asm volatile ("msr BASEPRI,%0" :: "r" (lock_key) : ); #endif } ================================================ FILE: sst_c/ports/arm-cm/sst_port.h ================================================ /*=========================================================================== * Super-Simple Tasker (SST/C) port to ARM Cortex-M * * Copyright (C) 2005-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ===========================================================================*/ #ifndef SST_PORT_H_ #define SST_PORT_H_ /* additional SST-PORT task attributes for ARM Cortex-M */ #define SST_PORT_TASK_ATTR \ uint32_t volatile *nvic_pend; \ uint32_t nvic_irq; /* additional SST-PORT task operations for ARM Cortex-M */ #define SST_PORT_TASK_OPER \ void SST_Task_activate(SST_Task * const me); \ void SST_Task_setIRQ(SST_Task * const me, uint8_t irq); \ void SST_Task_setPrio(SST_Task * const me, SST_TaskPrio prio); /* SST-PORT critical section */ #define SST_PORT_CRIT_STAT #define SST_PORT_CRIT_ENTRY() __asm volatile ("cpsid i") #define SST_PORT_CRIT_EXIT() __asm volatile ("cpsie i") /* SST-PORT pend the Task after posting an event * NOTE: executed inside SST critical section. */ #define SST_PORT_TASK_PEND() (*me->nvic_pend = me->nvic_irq) /* the idle SST callback for this SST port */ void SST_onIdle(void); /* the SST scheduler lock key type */ typedef uint32_t SST_LockKey; #endif /* SST_PORT_H_ */ ================================================ FILE: sst_c/ports/dspic/sst_port.c ================================================ /** * @file sst_port.c * @author ASHRAF (ashraf-masoud@elarabygroup.com) * @version 0.1 * @date 2023-06-20 */ /*=========================================================================== * Super-Simple Tasker (SST/C) port to dsPIC33ep * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ===========================================================================*/ #include "sst.h" /* Super-Simple Tasker (SST/C) */ #include "dbc_assert.h" /* Design By Contract (DBC) assertions */ #include "sst_port.h" DBC_MODULE_NAME("sst_port") /* for DBC assertions in this module */ #define IFS_BASE ((uint16_t volatile *)0x800U) //interrupt flag status (pend) #define IEC_BASE ((uint16_t volatile *)0x820U) //interrupt enable control #define IPC_BASE ((uint16_t volatile *)0x840U) //interrupt priority control static void interrupt_SetPriority(uint16_t IRQn, uint8_t priority) { //CLR IPC_BASE[IRQn/4] &= ~(0X7<< ((IRQn%4)*4)); //SET IPC_BASE[IRQn/4] |= priority << ((IRQn%4)*4); } static void interrupt_Enable(uint16_t IRQn) { IEC_BASE[IRQn/16] |= 1 << (IRQn%16); } /*..........................................................................*/ //critical section counter uint8_t g_crit_counter = 0; /* SST kernel facilities ---------------------------------------------------*/ void SST_init(void) { } /*..........................................................................*/ void SST_start(void) { } /* SST Task facilities -----------------------------------------------------*/ void SST_Task_setPrio(SST_Task * const me, SST_TaskPrio prio) { /*! @pre * - the IRQ number must be already set * - the priority must fit in the NVIC */ DBC_REQUIRE(200, (me->interrupt_num >= 0U) && (prio <= 0b111 && prio > 0)); /* convert the SST direct priority (1,2,..) to NVIC priority... */ //no need for dspic -> 1 lowest -> 7 highest SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); /* set the Task priority of the associated IRQ */ interrupt_SetPriority(me->interrupt_num, prio); /* enable the IRQ associated with the Task */ interrupt_Enable(me->interrupt_num); SST_PORT_CRIT_EXIT(); /* store the address of NVIC_PEND address and the IRQ bit */ me->interrupt_pend = &IFS_BASE[me->interrupt_num/16 ]; me->interrupt_num = 1<<(me->interrupt_num%16); } /*..........................................................................*/ void SST_Task_activate(SST_Task * const me) { /*! @pre the queue must have some events */ DBC_REQUIRE(300, me->nUsed > 0U); /* get the event out of the queue */ /* NOTE: no critical section because me->tail is accessed only * from this task */ SST_Evt const *e = me->qBuf[me->tail]; if (me->tail == 0U) { /* need to wrap the tail? */ me->tail = me->end; /* wrap around */ } else { --me->tail; } SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); if ((--me->nUsed) > 0U) { /* some events still present in the queue? */ *me->interrupt_pend |= me->interrupt_num; /* <=== pend the associated IRQ */ } SST_PORT_CRIT_EXIT(); /* dispatch the received event to this task */ (*me->dispatch)(me, e); /* NOTE: virtual call */ /* TBD: implement event recycling */ } /*..........................................................................*/ void SST_Task_setIRQ(SST_Task * const me, uint8_t irq) { me->interrupt_num = irq; } /*..........................................................................*/ SST_LockKey SST_Task_lock(SST_TaskPrio ceiling) { /* NOTE: * dsPIC support the Interrupt Priority Level -IPL- bits in Status Reg -SR- * and the selective SST scheduler locking * is implemented by setting IPL bits to the ceiling level. */ // save current Priority SST_LockKey basepri_ = SRbits.IPL; // Current base priority is lower than the ceiling if(basepri_ < ceiling) { // update the Processor Priority SRbits.IPL = ceiling; } else { //do nothing } return basepri_; } /*..........................................................................*/ void SST_Task_unlock(SST_LockKey lock_key) { SRbits.IPL = lock_key; } ================================================ FILE: sst_c/ports/dspic/sst_port.h ================================================ /** * @file sst_port.h * @author ASHRAF (ashrafkamel491@gmail.com) * @version 0.1 * @date 2023-06-20 */ /*=========================================================================== * Super-Simple Tasker (SST/C) port to DSPIC33ep * * Copyright (C) 2005-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ===========================================================================*/ #ifndef SST_PORT_H_ #define SST_PORT_H_ #include "xc.h" /* additional SST-PORT task attributes for ARM Cortex-M */ #define SST_PORT_TASK_ATTR \ uint16_t volatile *interrupt_pend; \ uint16_t interrupt_num; /* additional SST-PORT task operations for ARM Cortex-M */ #define SST_PORT_TASK_OPER \ void SST_Task_activate(SST_Task * const me); \ void SST_Task_setIRQ(SST_Task * const me, uint8_t irq); \ void SST_Task_setPrio(SST_Task * const me, SST_TaskPrio prio); /* SST-PORT critical section */ #define SST_PORT_CRIT_STAT #define SST_PORT_CRIT_ENTRY() \ do \ { \ extern uint8_t g_crit_counter; \ INTCON2bits.GIE = 0; \ g_crit_counter++; \ } while (0); #define SST_PORT_CRIT_EXIT() \ do \ { \ extern uint8_t g_crit_counter; \ g_crit_counter--; \ if (g_crit_counter == 0) \ { \ INTCON2bits.GIE = 1; \ } \ } while (0); /* SST-PORT pend the Task after posting an event * NOTE: executed inside SST critical section. */ #define SST_PORT_TASK_PEND() *me->interrupt_pend |= me->interrupt_num /* the idle SST callback for this SST port */ void SST_onIdle(void); /* the SST scheduler lock key type */ typedef uint16_t SST_LockKey; #endif /* SST_PORT_H_ */ ================================================ FILE: sst_c/src/sst.c ================================================ /*=========================================================================== * Super-Simple Tasker (SST/C) * * Copyright (C) 2006-2023 Quantum Leaps, . * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ===========================================================================*/ #include "sst.h" /* Super-Simple Tasker (SST) */ #include "dbc_assert.h" /* Design By Contract (DBC) assertions */ DBC_MODULE_NAME("sst") /* for DBC assertions in this module */ /*..........................................................................*/ int SST_Task_run(void) { SST_start(); /* port-specific start of multitasking */ SST_onStart(); /* application callback to config & start interrupts */ for (;;) { /* idle loop of the SST kernel */ SST_onIdle(); } } /*--------------------------------------------------------------------------*/ void SST_Task_ctor( SST_Task * const me, SST_Handler init, SST_Handler dispatch) { me->init = init; me->dispatch = dispatch; } /*..........................................................................*/ void SST_Task_start( SST_Task * const me, SST_TaskPrio prio, SST_Evt const **qBuf, SST_QCtr qLen, SST_Evt const * const ie) { /*! @pre * - the priority must be greater than zero * - the queue storage and length must be provided */ DBC_REQUIRE(200, (0U < prio) && (qBuf != (SST_Evt const **)0) && (qLen > 0U)); me->qBuf = qBuf; me->end = qLen - 1U; me->head = 0U; me->tail = 0U; me->nUsed = 0U; SST_Task_setPrio(me, prio); /* initialize this task with the initialization event */ (*me->init)(me, ie); /* NOTE: virtual call */ /* TBD: implement event recycling */ } /*..........................................................................*/ void SST_Task_post(SST_Task * const me, SST_Evt const * const e) { /*! @pre the queue must be sized adequately and cannot overflow */ DBC_REQUIRE(300, me->nUsed <= me->end); SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); me->qBuf[me->head] = e; /* insert event into the queue */ if (me->head == 0U) { /* need to wrap the head? */ me->head = me->end; /* wrap around */ } else { --me->head; } ++me->nUsed; SST_PORT_TASK_PEND(); SST_PORT_CRIT_EXIT(); } /*--------------------------------------------------------------------------*/ static SST_TimeEvt *timeEvt_head = (SST_TimeEvt *)0; /*..........................................................................*/ void SST_TimeEvt_ctor( SST_TimeEvt * const me, SST_Signal sig, SST_Task *task) { me->super.sig = sig; me->task = task; me->ctr = 0U; me->interval = 0U; /* insert time event "me" into the linked-list */ me->next = timeEvt_head; timeEvt_head = me; } /*..........................................................................*/ void SST_TimeEvt_arm( SST_TimeEvt * const me, SST_TCtr ctr, SST_TCtr interval) { SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); me->ctr = ctr; me->interval = interval; SST_PORT_CRIT_EXIT(); } /*..........................................................................*/ bool SST_TimeEvt_disarm(SST_TimeEvt * const me) { SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); bool status = (me->ctr != 0U); me->ctr = 0U; me->interval = 0U; SST_PORT_CRIT_EXIT(); return status; } /*..........................................................................*/ void SST_TimeEvt_tick(void) { for (SST_TimeEvt *t = timeEvt_head; t != (SST_TimeEvt *)0; t = t->next) { SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); if (t->ctr == 0U) { /* disarmed? (most frequent case) */ SST_PORT_CRIT_EXIT(); } else if (t->ctr == 1U) { /* expiring? */ t->ctr = t->interval; SST_PORT_CRIT_EXIT(); SST_Task_post(t->task, &t->super); } else { /* timing out */ --t->ctr; SST_PORT_CRIT_EXIT(); } } } ================================================ FILE: sst_cpp/README.txt ================================================ This directory contains the SST implementation in C++ roughly corresponding to the BCC2 conformance class in the OSEK/VDX Operating System specification. This SST implementation is referred to as "SST/C++". - "basic tasks" (non-blocking) - preemptive scheduling - multiple tasks per prioriy level - multiple "activations" per task (event queues) ================================================ FILE: sst_cpp/examples/README.txt ================================================ This directory contains examples for the preemptive SST/C++ kernel. ================================================ FILE: sst_cpp/examples/blinky/armclang/nucleo-l053r8.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 nucleo-l053r8 0x4 ARM-ADS 12000000 1 1 0 1 0 1 65535 0 0 0 79 66 8 .\build_nucleo-l053r8\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 UL2CM3 UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM)) 0 ST-LINKIII-KEIL_SWO -U066CFF484951775087074312 -O8431 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P2 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC800 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=1702,853,2113,1355,0)(1007=2082,245,2289,466,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS 1 2 0xE000E400 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 10000000 Application 1 0 0 0 1 1 5 0 0 0 ..\bsp.hpp bsp.hpp 0 0 1 2 8 0 0 0 ..\bsp_nucleo-l053r8.cpp bsp_nucleo-l053r8.cpp 0 0 1 3 8 0 0 0 ..\main.cpp main.cpp 0 0 1 4 8 0 0 0 ..\blinky.cpp blinky.cpp 0 0 1 5 5 0 0 0 ..\blinky.hpp blinky.hpp 0 0 nucleo-l053r8 1 0 0 0 2 6 2 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s startup_stm32l053xx.s 0 0 2 7 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l0xx.h 0 0 2 8 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h stm32l053xx.h 0 0 2 9 1 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c system_stm32l0xx.c 0 0 sst 1 0 0 0 3 10 8 0 0 0 ..\..\..\src\sst.cpp sst.cpp 0 0 sst_port 1 0 0 0 4 11 8 0 0 0 ..\..\..\ports\arm-cm\sst_port.cpp sst_port.cpp 0 0 4 12 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.hpp sst_port.hpp 0 0
================================================ FILE: sst_cpp/examples/blinky/armclang/nucleo-l053r8.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
nucleo-l053r8 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32L053R8Tx STMicroelectronics Keil.STM32L0xx_DFP.2.2.0 http://www.keil.com/pack/ IRAM(0x20000000,0x00002000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$Flash\STM32L0xx_64.FLM)) 0 $$Device:STM32L053R8Tx$Device\Include\stm32l0xx.h $$Device:STM32L053R8Tx$SVD\STM32L053x.svd 0 0 0 0 0 0 1 .\build_nucleo-l053r8\ blinky_button 1 0 0 1 1 .\build_nucleo-l053r8\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-l053r8\blinky_button.bin .\build_nucleo-l053r8\blinky_button.axf 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP DARMCM1.DLL -pCM0+ SARMCM3.DLL TARMCM1.DLL -pCM0+ 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M0+" 0 0 0 1 1 0 0 0 0 0 0 0 8 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 1 0x8000000 0x10000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x10000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 0 0x0 0x0 0 0 0 0 1 0 0 0 0 0 4 0 1 0 0 0 3 3 0 0 0 0 0 -Wno-padded .;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-l053r8 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Application bsp.hpp 5 ..\bsp.hpp bsp_nucleo-l053r8.cpp 8 ..\bsp_nucleo-l053r8.cpp main.cpp 8 ..\main.cpp blinky.cpp 8 ..\blinky.cpp blinky.hpp 5 ..\blinky.hpp nucleo-l053r8 startup_stm32l053xx.s 2 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s stm32l0xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l053xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h system_stm32l0xx.c 1 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c sst sst.cpp 8 ..\..\..\src\sst.cpp sst_port sst_port.cpp 8 ..\..\..\ports\arm-cm\sst_port.cpp sst_port.hpp 5 ..\..\..\ports\arm-cm\sst_port.hpp nucleo-l053r8 1
================================================ FILE: sst_cpp/examples/blinky/blinky.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky.hpp" // application shared interface namespace { DBC_MODULE_NAME("blinky") // for DBC assertions in this module */ } // unnamed namespace namespace App { //............................................................................ class Blinky : public SST::Task { SST::TimeEvt m_te1; SST::TimeEvt m_te2; public: Blinky(void); void init(SST::Evt const * const ie) override; void dispatch(SST::Evt const * const e) override; static Blinky inst; }; //............................................................................ Blinky Blinky::inst; // the Blinky instance SST::Task * const AO_Blinky = &Blinky::inst; // opaque AO pointer //............................................................................ Blinky::Blinky(void) : m_te1(TIMEOUT1_SIG, this), m_te2(TIMEOUT2_SIG, this) {} //............................................................................ void Blinky::init(SST::Evt const * const ie) { static_cast(ie); // unused parameter m_te2.arm(1U, 0U); } //............................................................................ void Blinky::dispatch(SST::Evt const * const e) { switch (e->sig) { case TIMEOUT1_SIG: { BSP::ledOff(); m_te2.arm(BSP::TICKS_PER_SEC*3U/4U, 0U); break; } case TIMEOUT2_SIG: { BSP::ledOn(); m_te1.arm(BSP::TICKS_PER_SEC/4U, 0U); break; } default: { DBC_ERROR(500); // unexpected event break; } } } } // namespace App ================================================ FILE: sst_cpp/examples/blinky/blinky.hpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #ifndef BLINKY_HPP_ #define BLINKY_HPP_ #include "dbc_assert.h" // Design By Contract (DBC) assertions namespace App { enum Signals { TIMEOUT1_SIG, TIMEOUT2_SIG, // ... MAX_SIG // the last signal }; extern SST::Task * const AO_Blinky; // opaque task pointer } // namespace App #endif // BLINKY_HPP_ ================================================ FILE: sst_cpp/examples/blinky/bsp.hpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // /// SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #ifndef BSP_HPP_ #define BSP_HPP_ namespace BSP { constexpr std::uint32_t TICKS_PER_SEC = 1000U; void init(void); void ledOn(void); void ledOff(void); } // namespace BSP #endif // BSP_HPP_ ================================================ FILE: sst_cpp/examples/blinky/bsp_nucleo-l053r8.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example for STM32 NUCLEO-L053R8 // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // // Copyright (C) 2005 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky.hpp" // application shared interface #include "stm32l0xx.h" // CMSIS-compliant header file for the MCU used // add other drivers if necessary... // Local-scope defines ------------------------------------------------------- namespace { //DBC_MODULE_NAME("bsp_nucleo-l053r8") // for DBC assertions in this module } // unnamed workspace // test pins on GPIO PA #define LED_PIN 5U // ISRs used in the application ============================================== extern "C" { void SysTick_Handler(void); // prototype void SysTick_Handler(void) { // system clock tick ISR SST::TimeEvt::tick(); } // Assertion handler ========================================================= void DBC_fault_handler(char const * const module, int const label) { // // NOTE: add here your application-specific error handling // (void)module; (void)label; // set PRIMASK to disable interrupts and stop SST right here __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { // keep blinking LED2 BSP::ledOn(); // turn LED2 on uint32_t volatile ctr; for (ctr = 10000U; ctr > 0U; --ctr) { } BSP::ledOff(); // turn LED2 off for (ctr = 10000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } //............................................................................ void assert_failed(char const * const module, int const label);// prototype void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } // SST task activations ====================================================== // preprocessor switch to choose between regular and reserved IRQs #define REGULAR_IRQS #ifdef REGULAR_IRQS // repurpose regular IRQs for SST Tasks // prototypes void PVD_IRQHandler(void); void PVD_IRQHandler(void) { App::AO_Blinky->activate(); } #else // use reserved IRQs for SST Tasks // prototypes void Reserved14_IRQHandler(void); // prototype // use reserved IRQs for SST Tasks void Reserved14_IRQHandler(void) { App::AO_Blinky->activate(); } #endif } // extern "C" namespace BSP { // BSP functions ============================================================= void init(void) { // Configure the MPU to prevent NULL-pointer dereferencing // see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu // MPU->RBAR = 0x0U // base address (NULL) | MPU_RBAR_VALID_Msk // valid region | (MPU_RBAR_REGION_Msk & 7U); // region #7 MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region | (0x0U << MPU_RASR_AP_Pos) // no-access region | MPU_RASR_ENABLE_Msk; // region enable MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region | MPU_CTRL_ENABLE_Msk; // enable the MPU __ISB(); __DSB(); // assign IRQs to tasks. NOTE: critical for SST... #ifdef REGULAR_IRQS // repurpose regular IRQs for SST Tasks App::AO_Blinky->setIRQ (PVD_IRQn); #else // use reserved IRQs for SST Tasks App::AO_Blinky->setIRQ (14U); #endif // enable GPIO port PA clock RCC->IOPENR |= (1U << 0U); // set all used GPIOA pins as push-pull output, no pull-up, pull-down GPIOA->MODER &= ~(3U << 2U*LED_PIN); GPIOA->MODER |= (1U << 2U*LED_PIN); GPIOA->OTYPER &= ~(1U << LED_PIN); GPIOA->PUPDR &= ~(3U << 2U*LED_PIN); } //............................................................................ void ledOn(void) { GPIOA->BSRR = (1U << LED_PIN); } void ledOff(void) { GPIOA->BSRR = (1U << (LED_PIN + 16U)); } } // namespace BSP // SST callbacks ============================================================= namespace SST { void onStart(void) { SystemCoreClockUpdate(); // set up the SysTick timer to fire at BSP::TICKS_PER_SEC rate SysTick_Config((SystemCoreClock / BSP::TICKS_PER_SEC) + 1U); // set priorities of ISRs used in the system NVIC_SetPriority(SysTick_IRQn, 0U); // ... } //............................................................................ void onIdle(void) { #ifdef NDEBUG // Put the CPU and peripherals to the low-power mode. // you might need to customize the clock management for your application, // see the datasheet for your particular Cortex-M MCU. // __WFI(); // Wait-For-Interrupt #endif } } // namespace SST ================================================ FILE: sst_cpp/examples/blinky/gnu/nucleo-l053r8.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST/C++) on NUCLEO-L053R8, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-01-22 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f nucleo-l053r8.mak # make -f nucleo-l053r8.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky TARGET := nucleo-l053r8 #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ system_stm32l0xx.c \ startup_stm32l053xx.c # C++ source files CPP_SRCS := \ sst.cpp \ sst_port.cpp \ main.cpp \ blinky.cpp \ bsp_nucleo-l053r8.cpp LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m0plus ARM_FPU := FLOAT_ABI := #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-g++ BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst_cpp/examples/blinky/iar/nucleo-l053r8.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst_cpp/examples/blinky/iar/nucleo-l053r8.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Debug Application $PROJ_DIR$\..\blinky.cpp $PROJ_DIR$\..\blinky.hpp $PROJ_DIR$\..\bsp.hpp $PROJ_DIR$\..\bsp_nucleo-l053r8.cpp $PROJ_DIR$\..\main.cpp nucleo-l053r8 $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\iar\startup_stm32l053xx.s $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c sst $PROJ_DIR$\..\..\..\src\sst.cpp sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.cpp $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.hpp ================================================ FILE: sst_cpp/examples/blinky/iar/nucleo-l053r8.eww ================================================ $WS_DIR$\nucleo-l053r8.ewp ================================================ FILE: sst_cpp/examples/blinky/main.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky.hpp" // application shared interface //............................................................................ int main() { SST::init(); // initialize the SST kernel BSP::init(); // initialize the Board Support Package // instantiate and start all SST tasks... static SST::Evt const *blinkyQSto[10]; // Event queue storage App::AO_Blinky->start( 1U, // SST-priority blinkyQSto, // storage for the AO's queue ARRAY_NELEM(blinkyQSto), // queue length nullptr); // initialization event (not used) return SST::Task::run(); // run the SST tasks // NOTE: in embedded systems SST::Task::run() should not return } ================================================ FILE: sst_cpp/examples/blinky_button/armclang/ek-tm4c123gxl.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 ek-tm4c123gxl 0x4 ARM-ADS 12000000 1 1 1 0 0 1 65535 0 0 0 79 66 8 .\build_ek-tm4c123gxl\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 4 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 0 0 19 BIN\lmidk-agdi.dll 0 DLGUARM 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 UL2CM3 UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0TM4C123_256 -FL040000 -FS00 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM) 0 DLGTARM (1010=2431,200,2881,757,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=1881,651,2358,966,0) 0 ARMDBGFLAGS 0 lmidk-agdi -U0E10259B -O4686 -S5 -FO29 0 0 114 1
1780
0 0 0 0 0 1 ..\bsp_ek-tm4c123gxl.cpp \\blinky_button\../bsp_ek-tm4c123gxl.cpp\114
1 2 0x0 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Applicatioin 1 0 0 0 1 1 8 0 0 0 ..\blinky1.cpp blinky1.cpp 0 0 1 2 8 0 0 0 ..\blinky3.cpp blinky3.cpp 0 0 1 3 8 0 0 0 ..\bsp_ek-tm4c123gxl.cpp bsp_ek-tm4c123gxl.cpp 0 0 1 4 8 0 0 0 ..\button2a.cpp button2a.cpp 0 0 1 5 8 0 0 0 ..\button2b.cpp button2b.cpp 0 0 1 6 8 0 0 0 ..\main.cpp main.cpp 0 0 1 7 5 0 0 0 ..\blinky_button.hpp blinky_button.hpp 0 0 1 8 5 0 0 0 ..\bsp.hpp bsp.hpp 0 0 ek-tm4c123gxl 1 0 0 0 2 9 2 0 0 0 ..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s startup_TM4C123GH6PM.s 0 0 2 10 1 0 0 0 ..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c system_TM4C123GH6PM.c 0 0 2 11 5 0 0 0 ..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h TM4C123GH6PM.h 0 0 sst 1 0 0 0 3 12 8 0 0 0 ..\..\..\src\sst.cpp sst.cpp 0 0 sst_port 1 0 0 0 4 13 8 0 0 0 ..\..\..\ports\arm-cm\sst_port.cpp sst_port.cpp 0 0 4 14 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.hpp sst_port.hpp 0 0
================================================ FILE: sst_cpp/examples/blinky_button/armclang/ek-tm4c123gxl.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
ek-tm4c123gxl 0x4 ARM-ADS 6220000::V6.22::ARMCLANG 1 TM4C123GH6PM Texas Instruments Keil.TM4C_DFP.1.1.0 http://www.keil.com/pack/ IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0TM4C123_256 -FS00 -FL040000 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM)) 0 $$Device:TM4C123GH6PM$Device\Include\TM4C123\TM4C123.h $$Device:TM4C123GH6PM$SVD\TM4C123\TM4C123GH6PM.svd 0 0 0 0 0 0 1 .\build_ek-tm4c123gxl\ blinky_button 1 0 0 1 1 .\build_ek-tm4c123gxl\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -MPU DCM.DLL -pCM4 SARMCM3.DLL -MPU TCM.DLL -pCM4 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL "" () 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M4" 0 0 0 1 1 0 0 2 0 0 0 0 0 8 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x8000 1 0x0 0x40000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x40000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x8000 0 0x0 0x0 0 1 0 0 1 0 0 0 0 0 3 0 1 0 0 0 3 3 0 0 0 0 0 -Wno-c11-extensions -Wno-padded __FPU_PRESENT ..;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\ek-tm4c123gxl 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Applicatioin blinky1.cpp 8 ..\blinky1.cpp blinky3.cpp 8 ..\blinky3.cpp bsp_ek-tm4c123gxl.cpp 8 ..\bsp_ek-tm4c123gxl.cpp button2a.cpp 8 ..\button2a.cpp button2b.cpp 8 ..\button2b.cpp main.cpp 8 ..\main.cpp blinky_button.hpp 5 ..\blinky_button.hpp bsp.hpp 5 ..\bsp.hpp ek-tm4c123gxl startup_TM4C123GH6PM.s 2 ..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s system_TM4C123GH6PM.c 1 ..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c TM4C123GH6PM.h 5 ..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h sst sst.cpp 8 ..\..\..\src\sst.cpp sst_port sst_port.cpp 8 ..\..\..\ports\arm-cm\sst_port.cpp sst_port.hpp 5 ..\..\..\ports\arm-cm\sst_port.hpp ek-tm4c123gxl 1
================================================ FILE: sst_cpp/examples/blinky_button/armclang/nucleo-c031c6.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 nucleo-c031c6 0x4 ARM-ADS 12000000 1 1 0 1 0 1 65535 0 0 0 79 66 8 .\build_nucleo-c031c6\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 ST-LINKIII-KEIL_SWO -U-O206 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 UL2CM3 UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) 0 lmidk-agdi -U0E10259B -O4622 -S3 -FO29 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=1150,195,1600,752,0)(1007=-1,-1,-1,-1,0)(1008=1224,174,1600,410,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS 0 0 120 1
134219768
0 0 0 0 0 1 C:\GitHub\Super-Simple-Tasker\sst_cpp\examples\blinky_button\bsp_nucleo-c031c6.c \\blinky_button\../bsp_nucleo-c031c6.c\120
1 0 0 1
134221496
0 0 0 0 0 1
0 1 OS_curr 1 1 OS_next 2 1 OS_readySet 1 2 0x200000f0 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 2 10000000
Application 1 0 0 0 1 1 5 0 0 0 ..\blinky_button.hpp blinky_button.hpp 0 0 1 2 8 0 0 0 ..\blinky1.cpp blinky1.cpp 0 0 1 3 8 0 0 0 ..\blinky3.cpp blinky3.cpp 0 0 1 4 5 0 0 0 ..\bsp.hpp bsp.hpp 0 0 1 5 8 0 0 0 ..\bsp_nucleo-c031c6.cpp bsp_nucleo-c031c6.cpp 0 0 1 6 8 0 0 0 ..\button2a.cpp button2a.cpp 0 0 1 7 8 0 0 0 ..\button2b.cpp button2b.cpp 0 0 1 8 8 0 0 0 ..\main.cpp main.cpp 0 0 nucleo-c031c6 1 0 0 0 2 9 5 0 0 0 ..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h stm32c031xx.h 0 0 2 10 1 0 0 0 ..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c system_stm32c0xx.c 0 0 2 11 2 0 0 0 ..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s startup_stm32c031xx.s 0 0 sst 1 0 0 0 3 12 8 0 0 0 ..\..\..\src\sst.cpp sst.cpp 0 0 sst_port 1 0 0 0 4 13 8 0 0 0 ..\..\..\ports\arm-cm\sst_port.cpp sst_port.cpp 0 0 4 14 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.hpp sst_port.hpp 0 0
================================================ FILE: sst_cpp/examples/blinky_button/armclang/nucleo-c031c6.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
nucleo-c031c6 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32C031C6Tx STMicroelectronics Keil.STM32C0xx_DFP.1.0.0 https://www.keil.com/pack/ IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) 0 $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd 0 0 0 0 0 0 1 .\build_nucleo-c031c6\ blinky_button 1 0 0 1 1 .\build_nucleo-c031c6\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-c031c6\blinky_button.bin .\build_nucleo-c031c6\blinky_button.axf 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP-MPU DARMCM1.DLL -pCM0+ SARMCM3.DLL -MPU TARMCM1.DLL -pCM0+ 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL "" () 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M0+" 0 0 0 1 1 0 0 0 0 0 0 0 8 1 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x3000 1 0x8000000 0x8000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x8000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x3000 0 0x0 0x0 0 0 0 0 1 0 0 0 0 0 3 0 1 1 0 0 3 3 0 0 0 0 0 -Wconditional-uninitialized -Wsometimes-uninitialized .;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-c031c6 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Application blinky_button.hpp 5 ..\blinky_button.hpp blinky1.cpp 8 ..\blinky1.cpp blinky3.cpp 8 ..\blinky3.cpp bsp.hpp 5 ..\bsp.hpp bsp_nucleo-c031c6.cpp 8 ..\bsp_nucleo-c031c6.cpp button2a.cpp 8 ..\button2a.cpp button2b.cpp 8 ..\button2b.cpp main.cpp 8 ..\main.cpp nucleo-c031c6 stm32c031xx.h 5 ..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h system_stm32c0xx.c 1 ..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c startup_stm32c031xx.s 2 ..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s sst sst.cpp 8 ..\..\..\src\sst.cpp sst_port sst_port.cpp 8 ..\..\..\ports\arm-cm\sst_port.cpp sst_port.hpp 5 ..\..\..\ports\arm-cm\sst_port.hpp ek-tm4c123gxl 1
================================================ FILE: sst_cpp/examples/blinky_button/armclang/nucleo-h743zi.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 arm-nucleo-h743zi 0x4 ARM-ADS 12000000 1 1 1 0 0 1 65535 0 0 0 79 66 8 .\build_nucleo-h743zi\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 0 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 UL2CM3 UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0STM32H7x_2048 -FL0200000 -FS08000000 -FP0($$Device:STM32H743ZITx$CMSIS\Flash\STM32H7x_2048.FLM) 0 ST-LINKIII-KEIL_SWO -U0675FF504955857567065746 -O8399 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P2 -N00("ARM CoreSight SW-DP (ARM Core") -D00(6BA02477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20010000 -FC1000 -FN1 -FF0STM32H7x_2048.FLM -FS08000000 -FL0200000 -FP0($$Device:STM32H743ZITx$CMSIS\Flash\STM32H7x_2048.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=2346,607,2796,1164,1)(6017=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(6016=-1,-1,-1,-1,0)(1012=3268,1338,3745,1653,0) 0 ARMDBGFLAGS 0 1 nvic_prio_shift 1 2 0xE000ED08 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 10000000 Applicatioin 1 0 0 0 1 1 5 0 0 0 ..\blinky_button.hpp blinky_button.hpp 0 0 1 2 8 0 0 0 ..\blinky1.cpp blinky1.cpp 0 0 1 3 8 0 0 0 ..\blinky3.cpp blinky3.cpp 0 0 1 4 5 0 0 0 ..\bsp.hpp bsp.hpp 0 0 1 5 8 0 0 0 ..\bsp_nucleo-h743zi.cpp bsp_nucleo-h743zi.cpp 0 0 1 6 8 0 0 0 ..\button2a.cpp button2a.cpp 0 0 1 7 8 0 0 0 ..\button2b.cpp button2b.cpp 0 0 1 8 8 0 0 0 ..\main.cpp main.cpp 0 0 nucleo-h743zi 1 0 0 0 2 9 2 0 0 0 ..\..\..\..\3rd_party\nucleo-h743zi\arm\startup_stm32h743xx.s startup_stm32h743xx.s 0 0 2 10 5 0 0 0 ..\..\..\..\3rd_party\nucleo-h743zi\stm32h743xx.h stm32h743xx.h 0 0 2 11 1 0 0 0 ..\..\..\..\3rd_party\nucleo-h743zi\system_stm32h7xx.c system_stm32h7xx.c 0 0 sst 1 0 0 0 3 12 8 0 0 0 ..\..\..\src\sst.cpp sst.cpp 0 0 sst_port 1 0 0 0 4 13 8 0 0 0 ..\..\..\ports\arm-cm\sst_port.cpp sst_port.cpp 0 0 4 14 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.hpp sst_port.hpp 0 0
================================================ FILE: sst_cpp/examples/blinky_button/armclang/nucleo-h743zi.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
arm-nucleo-h743zi 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32H743ZITx STMicroelectronics Keil.STM32H7xx_DFP.3.0.0 http://www.keil.com/pack/ IRAM(0x20000000,0x00020000) IRAM2(0x24000000,0x00080000) IROM(0x08000000,0x00200000) CPUTYPE("Cortex-M7") FPU3(DFPU) CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32H7x_2048 -FS08000000 -FL0200000 -FP0($$Device:STM32H743ZITx$CMSIS\Flash\STM32H7x_2048.FLM)) 0 $$Device:STM32H743ZITx$Drivers\CMSIS\Device\ST\STM32H7xx\Include\stm32h7xx.h $$Device:STM32H743ZITx$CMSIS\SVD\STM32H7x3.svd 0 0 0 0 0 0 1 .\build_nucleo-h743zi\ blinky_button 1 0 0 1 1 .\build_nucleo-h743zi\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-h743zi\blinky_button.bin .\build_nucleo-h743zi\blinky_button.axf 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP -MPU DCM.DLL -pCM7 SARMCM3.DLL -MPU TCM.DLL -pCM7 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL "" () 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M7" 0 0 0 1 1 0 0 3 0 0 1 0 8 0 0 0 0 3 4 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x20000 1 0x8000000 0x200000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x200000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x20000 0 0x24000000 0x80000 0 1 0 0 1 0 0 0 0 0 3 0 1 0 0 0 3 3 0 0 0 0 0 STM32H743xx .;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-h743zi 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Applicatioin blinky_button.hpp 5 ..\blinky_button.hpp blinky1.cpp 8 ..\blinky1.cpp blinky3.cpp 8 ..\blinky3.cpp bsp.hpp 5 ..\bsp.hpp bsp_nucleo-h743zi.cpp 8 ..\bsp_nucleo-h743zi.cpp button2a.cpp 8 ..\button2a.cpp button2b.cpp 8 ..\button2b.cpp main.cpp 8 ..\main.cpp nucleo-h743zi startup_stm32h743xx.s 2 ..\..\..\..\3rd_party\nucleo-h743zi\arm\startup_stm32h743xx.s stm32h743xx.h 5 ..\..\..\..\3rd_party\nucleo-h743zi\stm32h743xx.h system_stm32h7xx.c 1 ..\..\..\..\3rd_party\nucleo-h743zi\system_stm32h7xx.c sst sst.cpp 8 ..\..\..\src\sst.cpp sst_port sst_port.cpp 8 ..\..\..\ports\arm-cm\sst_port.cpp sst_port.hpp 5 ..\..\..\ports\arm-cm\sst_port.hpp nucleo-h743zi 1
================================================ FILE: sst_cpp/examples/blinky_button/armclang/nucleo-l053r8.uvoptx ================================================ 1.0
### uVision Project, (C) Keil Software
*.c *.s*; *.src; *.a* *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm *.cpp 0 0 0 nucleo-l053r8 0x4 ARM-ADS 12000000 1 1 0 1 0 1 65535 0 0 0 79 66 8 .\build_nucleo-l053r8\ 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 18 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 0 0 6 STLink\ST-LINKIII-KEIL_SWO.dll 0 UL2CM3 UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM)) 0 ST-LINKIII-KEIL_SWO -U066CFF484951775087074312 -O8431 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P2 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC800 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) 0 DLGUARM (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 0 DLGTARM (1010=1702,853,2113,1355,0)(1007=2082,245,2289,466,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS 1 2 0xE000E400 0 2 0 0x400 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 10000000 Application 1 0 0 0 1 1 5 0 0 0 ..\blinky_button.hpp blinky_button.hpp 0 0 1 2 8 0 0 0 ..\blinky1.cpp blinky1.cpp 0 0 1 3 8 0 0 0 ..\blinky3.cpp blinky3.cpp 0 0 1 4 5 0 0 0 ..\bsp.hpp bsp.hpp 0 0 1 5 8 0 0 0 ..\bsp_nucleo-l053r8.cpp bsp_nucleo-l053r8.cpp 0 0 1 6 8 0 0 0 ..\button2a.cpp button2a.cpp 0 0 1 7 8 0 0 0 ..\button2b.cpp button2b.cpp 0 0 1 8 8 0 0 0 ..\main.cpp main.cpp 0 0 nucleo-l053r8 1 0 0 0 2 9 2 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s startup_stm32l053xx.s 0 0 2 10 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l0xx.h 0 0 2 11 5 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h stm32l053xx.h 0 0 2 12 1 0 0 0 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c system_stm32l0xx.c 0 0 sst 1 0 0 0 3 13 8 0 0 0 ..\..\..\src\sst.cpp sst.cpp 0 0 sst_port 1 0 0 0 4 14 8 0 0 0 ..\..\..\ports\arm-cm\sst_port.cpp sst_port.cpp 0 0 4 15 5 0 0 0 ..\..\..\ports\arm-cm\sst_port.hpp sst_port.hpp 0 0
================================================ FILE: sst_cpp/examples/blinky_button/armclang/nucleo-l053r8.uvprojx ================================================ 2.1
### uVision Project, (C) Keil Software
nucleo-l053r8 0x4 ARM-ADS 6160000::V6.16::ARMCLANG 1 STM32L053R8Tx STMicroelectronics Keil.STM32L0xx_DFP.2.2.0 http://www.keil.com/pack/ IRAM(0x20000000,0x00002000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$Flash\STM32L0xx_64.FLM)) 0 $$Device:STM32L053R8Tx$Device\Include\stm32l0xx.h $$Device:STM32L053R8Tx$SVD\STM32L053x.svd 0 0 0 0 0 0 1 .\build_nucleo-l053r8\ blinky_button 1 0 0 1 1 .\build_nucleo-l053r8\ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 fromelf --bin --output .\build_nucleo-l053r8\blinky_button.bin .\build_nucleo-l053r8\blinky_button.axf 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 3 1 SARMCM3.DLL -REMAP DARMCM1.DLL -pCM0+ SARMCM3.DLL TARMCM1.DLL -pCM0+ 1 0 0 0 16 1 0 0 1 1 4096 1 BIN\UL2CM3.DLL 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 "Cortex-M0+" 0 0 0 1 1 0 0 0 0 0 0 0 8 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 1 0x8000000 0x10000 0 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x0 0x0 1 0x8000000 0x10000 1 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x0 0x0 0 0x20000000 0x2000 0 0x0 0x0 0 0 0 0 1 0 0 0 0 0 4 0 1 0 0 0 3 3 0 0 0 0 0 -Wno-padded .;..\..\..\..\include;..\..\..\ports\arm-cm;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\nucleo-l053r8 1 0 0 0 0 0 0 1 0 4 Stack_Size=2048 Heap_Size=16 1 0 0 0 1 0 0x00000000 0x20000000 --entry Reset_Handler Application blinky_button.hpp 5 ..\blinky_button.hpp blinky1.cpp 8 ..\blinky1.cpp blinky3.cpp 8 ..\blinky3.cpp bsp.hpp 5 ..\bsp.hpp bsp_nucleo-l053r8.cpp 8 ..\bsp_nucleo-l053r8.cpp button2a.cpp 8 ..\button2a.cpp button2b.cpp 8 ..\button2b.cpp main.cpp 8 ..\main.cpp nucleo-l053r8 startup_stm32l053xx.s 2 ..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s stm32l0xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h stm32l053xx.h 5 ..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h system_stm32l0xx.c 1 ..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c sst sst.cpp 8 ..\..\..\src\sst.cpp sst_port sst_port.cpp 8 ..\..\..\ports\arm-cm\sst_port.cpp sst_port.hpp 5 ..\..\..\ports\arm-cm\sst_port.hpp nucleo-l053r8 1
================================================ FILE: sst_cpp/examples/blinky_button/blinky1.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface namespace { DBC_MODULE_NAME("blinky1") // for DBC assertions in this module */ } // unnamed namespace namespace App { //............................................................................ class Blinky1 : public SST::Task { SST::TimeEvt m_te; std::uint16_t m_toggles; public: Blinky1(void); void init(SST::Evt const * const ie) override; void dispatch(SST::Evt const * const e) override; static Blinky1 inst; }; //............................................................................ Blinky1 Blinky1::inst; // the Blinky1 instance SST::Task * const AO_Blinky1 = &Blinky1::inst; // opaque AO pointer //............................................................................ Blinky1::Blinky1(void) : m_te(TIMEOUT_SIG, this) {} //............................................................................ void Blinky1::init(SST::Evt const * const ie) { /* the initial event must be provided and must be WORKLOAD_SIG */ DBC_REQUIRE(300, (ie != nullptr) && (ie->sig == BLINKY_WORK_SIG)); m_te.arm( SST::evt_downcast(ie)->ticks, SST::evt_downcast(ie)->ticks); m_toggles = SST::evt_downcast(ie)->toggles; } //............................................................................ void Blinky1::dispatch(SST::Evt const * const e) { switch (e->sig) { case TIMEOUT_SIG: { for (std::uint16_t i = m_toggles; i > 0U; --i) { // just to exercise SST task scheduler lock... SST::LockKey key = lock(3U); BSP::d5on(); BSP::d5off(); unlock(key); } break; } case BLINKY_WORK_SIG: { BSP::d5on(); m_te.arm( SST::evt_downcast(e)->ticks, SST::evt_downcast(e)->ticks); m_toggles = SST::evt_downcast(e)->toggles; BSP::d5off(); break; } default: { DBC_ERROR(500); // unexpected event break; } } } } // namespace App ================================================ FILE: sst_cpp/examples/blinky_button/blinky3.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface namespace { DBC_MODULE_NAME("blinky3") // for DBC assertions in this module } // unnamed namespace namespace App { //............................................................................ class Blinky3 : public SST::Task { SST::TimeEvt m_te; std::uint16_t m_toggles; public: Blinky3(void); void init(SST::Evt const * const ie) override; void dispatch(SST::Evt const * const e) override; static Blinky3 inst; }; //............................................................................ Blinky3 Blinky3::inst; // the Blinky3 instance SST::Task * const AO_Blinky3 = &Blinky3::inst; // opaque AO pointer //............................................................................ Blinky3::Blinky3(void) : m_te(TIMEOUT_SIG, this) {} //............................................................................ void Blinky3::init(SST::Evt const * const ie) { // the initial event must be provided and must be WORKLOAD_SIG DBC_REQUIRE(300, (ie != nullptr) && (ie->sig == BLINKY_WORK_SIG)); m_te.arm( SST::evt_downcast(ie)->ticks, SST::evt_downcast(ie)->ticks); m_toggles = SST::evt_downcast(ie)->toggles; } //............................................................................ void Blinky3::dispatch(SST::Evt const * const e) { switch (e->sig) { case TIMEOUT_SIG: { for (std::uint16_t i = m_toggles; i > 0U; --i) { BSP::d2on(); BSP::d2off(); } break; } case BLINKY_WORK_SIG: { BSP::d2on(); m_te.arm( SST::evt_downcast(e)->ticks, SST::evt_downcast(e)->ticks); m_toggles = SST::evt_downcast(e)->toggles; BSP::d2off(); break; } default: { DBC_ERROR(500); // unexpected event break; } } } } // namespace App ================================================ FILE: sst_cpp/examples/blinky_button/blinky_button.hpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #ifndef BLINKY_BUTTON_HPP_ #define BLINKY_BUTTON_HPP_ #include "dbc_assert.h" // Design By Contract (DBC) assertions namespace App { enum Signals { TIMEOUT_SIG, BUTTON_PRESSED_SIG, BUTTON_RELEASED_SIG, BLINKY_WORK_SIG, FORWARD_PRESSED_SIG, FORWARD_RELEASED_SIG, // ... MAX_SIG // the last signal }; // event with parameters struct BlinkyWorkEvt { SST::Evt super; std::uint16_t toggles; // number of toggles of the signal std::uint8_t ticks; // number of clock ticks between }; // event with parameters struct ButtonWorkEvt { SST::Evt super; std::uint16_t toggles; // number of toggles of the signal }; extern SST::Task * const AO_Blinky1; // opaque task pointer extern SST::Task * const AO_Blinky3; // opaque task pointer extern SST::Task * const AO_Button2a; // opaque task pointer extern SST::Task * const AO_Button2b; // opaque task pointer } // namespace App #endif // BLINKY_BUTTON_HPP_ ================================================ FILE: sst_cpp/examples/blinky_button/bsp.hpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // /// SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #ifndef BSP_HPP_ #define BSP_HPP_ namespace BSP { constexpr std::uint32_t TICKS_PER_SEC = 1000U; void init(void); void d1on(void); void d1off(void); void d2on(void); void d2off(void); void d3on(void); void d3off(void); void d4on(void); void d4off(void); void d5on(void); void d5off(void); void d6on(void); void d6off(void); // immutable events for Blinky tasks SST::Evt const *getWorkEvtBlinky1(std::uint8_t num); SST::Evt const *getWorkEvtBlinky3(std::uint8_t num); } // namespace BSP #endif // BSP_HPP_ ================================================ FILE: sst_cpp/examples/blinky_button/bsp_ek-tm4c123gxl.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example for TivaC TM4C123GXL // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // // Copyright (C) 2005 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface #include "TM4C123GH6PM.h" // the device specific header (TI) #include // to exercise the FPU // add other drivers if necessary... // Local-scope defines ------------------------------------------------------- namespace { DBC_MODULE_NAME("bsp_ek-tm4c123gxl") // for DBC assertions in this module } // unnamed workspace /* test pins on GPIOF */ #define TST1_PIN (1U << 1U) /* LED Red */ #define TST2_PIN (1U << 2U) /* LED Blue */ /* test pins on GPIOD */ #define TST3_PIN (1U << 0U) #define TST4_PIN (1U << 1U) #define TST5_PIN (1U << 2U) /* test pins on GPIOF */ #define TST6_PIN (1U << 3U) /* LED Green */ /* Button on the board on GPIOF */ #define BTN_SW1 (1U << 4) // ISRs used in the application ============================================== extern "C" { void SysTick_Handler(void) { // system clock tick ISR BSP::d1on(); SST::TimeEvt::tick(); // get state of the user button // Perform the debouncing of buttons. The algorithm for debouncing // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle // and Michael Barr, page 71. // static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = ~GPIOF_AHB->DATA_Bits[BTN_SW1]; uint32_t tmp = buttons.depressed; // save the debounced depressed buttons.depressed |= (buttons.previous & current); // set depressed buttons.depressed &= (buttons.previous | current); // clear released buttons.previous = current; // update the history tmp ^= buttons.depressed; // changed debounced depressed if ((tmp & BTN_SW1) != 0U) { /* debounced SW1 state changed? */ if ((buttons.depressed & BTN_SW1) != 0U) { /* is SW1 depressed? */ // immutable button-press event static App::ButtonWorkEvt const pressEvt = { { App::BUTTON_PRESSED_SIG }, 60U }; // immutable forward-press event static App::ButtonWorkEvt const fPressEvt = { { App::FORWARD_PRESSED_SIG }, 60U }; App::AO_Button2a->post(&fPressEvt.super); App::AO_Button2a->post(&pressEvt.super); } else { // B1 is released // immutable button-release event static App::ButtonWorkEvt const releaseEvt = { { App::BUTTON_RELEASED_SIG }, 80U }; // immutable forward-release event static App::ButtonWorkEvt const fReleaseEvt = { { App::FORWARD_RELEASED_SIG }, 80U }; App::AO_Button2a->post(&fReleaseEvt.super); App::AO_Button2a->post(&releaseEvt.super); } } BSP::d1off(); } // Assertion handler ========================================================= void DBC_fault_handler(char const * const module, int const label) { // // NOTE: add here your application-specific error handling // (void)module; (void)label; // set PRIMASK to disable interrupts and stop SST right here __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { // keep blinking LED2 BSP::d6on(); // turn LED2 on uint32_t volatile ctr; for (ctr = 1000000U; ctr > 0U; --ctr) { } BSP::d6off(); // turn LED2 off for (ctr = 1000000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } //............................................................................ void assert_failed(char const * const module, int const label);// prototype void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } // SST task activations ====================================================== // repurpose regular IRQs for SST Tasks // prototypes void PWM1Gen0_IRQHandler(void); void PWM1Gen1_IRQHandler(void); void PWM1Gen2_IRQHandler(void); void PWM1Gen3_IRQHandler(void); void PWM1Gen0_IRQHandler(void) { App::AO_Blinky3->activate(); } void PWM1Gen1_IRQHandler(void) { App::AO_Button2b->activate(); } void PWM1Gen2_IRQHandler(void) { App::AO_Button2a->activate(); } void PWM1Gen3_IRQHandler(void) { App::AO_Blinky1->activate(); } } // extern "C" namespace BSP { // BSP functions ============================================================= void init(void) { // Configure the MPU to prevent NULL-pointer dereferencing // see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu // MPU->RBAR = 0x0U // base address (NULL) | MPU_RBAR_VALID_Msk // valid region | (MPU_RBAR_REGION_Msk & 7U); // region #7 MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region | (0x0U << MPU_RASR_AP_Pos) // no-access region | MPU_RASR_ENABLE_Msk; // region enable MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region | MPU_CTRL_ENABLE_Msk; // enable the MPU __ISB(); __DSB(); // assign IRQs to tasks. NOTE: critical for SST... App::AO_Blinky3->setIRQ(PWM1_0_IRQn); App::AO_Button2b->setIRQ(PWM1_1_IRQn); App::AO_Button2a->setIRQ(PWM1_2_IRQn); App::AO_Blinky1->setIRQ(PWM1_3_IRQn); SYSCTL->RCGCGPIO |= (1U << 5U); /* enable Run mode for GPIOF */ SYSCTL->RCGCGPIO |= (1U << 3U); /* enable Run mode for GPIOD */ __ISB(); __DSB(); SYSCTL->GPIOHBCTL |= (1U << 5); /* enable AHB for GPIOF */ SYSCTL->GPIOHBCTL |= (1U << 3); /* enable AHB for GPIOD */ __ISB(); __DSB(); /* configure test pins on GPIOF (digital output) */ GPIOF_AHB->DIR |= (TST1_PIN | TST2_PIN | TST6_PIN); GPIOF_AHB->DEN |= (TST1_PIN | TST2_PIN | TST6_PIN); /* configure button on GPIOF (digital input) */ GPIOF_AHB->DIR &= ~(BTN_SW1); /* input */ GPIOF_AHB->DEN |= (BTN_SW1); /* digital enable */ GPIOF_AHB->PUR |= (BTN_SW1); /* pull-up resistor enable */ /* configure test pins on GPIOD (digital output) */ GPIOD_AHB->DIR |= (TST3_PIN | TST4_PIN | TST5_PIN); GPIOD_AHB->DEN |= (TST3_PIN | TST4_PIN | TST5_PIN); } //............................................................................ #if defined __ARMCC_VERSION #elif defined __GNUC__ std::uint32_t __errno; // GNU-ARM needs this to link sqrtf() #endif static void exerciseFPU(float x) { // exercise the single-precision FPU by calculating the identity: // sqrt(x) == x / sqrt(x) for x > 0 // float tmp1 = sqrtf(x); // single-precision sqrt() float tmp2 = x / tmp1; DBC_ENSURE(200, (tmp1 - 1e-4f <= tmp2) && (tmp2 <= tmp1 + 1e-4f)); } //............................................................................ void d1on(void) { // LED-Red */ GPIOF_AHB->DATA_Bits[TST1_PIN] = 0xFFU; // don't use the FPU in the ISR } void d1off(void) { GPIOF_AHB->DATA_Bits[TST1_PIN] = 0x00U; } //............................................................................ void d2on(void) { /* LED-Blue */ GPIOF_AHB->DATA_Bits[TST2_PIN] = 0xFFU; exerciseFPU(1.2345f); } void d2off(void) { GPIOF_AHB->DATA_Bits[TST2_PIN] = 0x00U; } //............................................................................ void d3on(void) { GPIOD_AHB->DATA_Bits[TST3_PIN] = 0xFFU; exerciseFPU(0.345f); } void d3off(void) { GPIOD_AHB->DATA_Bits[TST3_PIN] = 0x00U; } //............................................................................ void d4on(void) { GPIOD_AHB->DATA_Bits[TST4_PIN] = 0xFFU; exerciseFPU(0.456f); } void d4off(void) { GPIOD_AHB->DATA_Bits[TST4_PIN] = 0x00U; } //............................................................................ void d5on(void) { GPIOD_AHB->DATA_Bits[TST5_PIN] = 0xFFU; exerciseFPU(1.567f); } void d5off(void) { GPIOD_AHB->DATA_Bits[TST5_PIN] = 0x00U; } //............................................................................ void d6on(void) { /* LED2-Green */ GPIOF_AHB->DATA_Bits[TST6_PIN] = 0xFFU; exerciseFPU(1.2345f); } void d6off(void) { GPIOF_AHB->DATA_Bits[TST6_PIN] = 0x00U; } //............................................................................ SST::Evt const *getWorkEvtBlinky1(uint8_t num) { // immutable work events for Blinky1 static App::BlinkyWorkEvt const workBlinky1[] = { { { App::BLINKY_WORK_SIG }, 40U, 5U }, { { App::BLINKY_WORK_SIG }, 30U, 7U } }; DBC_REQUIRE(500, num < ARRAY_NELEM(workBlinky1)); // num must be in range return &workBlinky1[num].super; } //............................................................................ SST::Evt const *getWorkEvtBlinky3(uint8_t num) { // immutable work events for Blinky3 static App::BlinkyWorkEvt const workBlinky3[] = { { { App::BLINKY_WORK_SIG }, 20U, 5U }, { { App::BLINKY_WORK_SIG }, 10U, 3U } }; DBC_REQUIRE(600, num < ARRAY_NELEM(workBlinky3)); // num must be in range return &workBlinky3[num].super; } } // namespace BSP // SST callbacks ============================================================= namespace SST { void onStart(void) { SystemCoreClockUpdate(); // set up the SysTick timer to fire at BSP::TICKS_PER_SEC rate SysTick_Config((SystemCoreClock / BSP::TICKS_PER_SEC) + 1U); // set priorities of ISRs used in the system NVIC_SetPriority(SysTick_IRQn, 0U); // ... } //............................................................................ void onIdle(void) { BSP::d6on(); // turn LED-Green on #ifdef NDEBUG // Put the CPU and peripherals to the low-power mode. // you might need to customize the clock management for your application, // see the datasheet for your particular Cortex-M MCU. // BSP::d6off(); // turn LED-Green off __WFI(); // Wait-For-Interrupt BSP::d6on(); // turn LED-Green on #else #endif BSP::d6off(); // turn LED-Green off } } // namespace SST ================================================ FILE: sst_cpp/examples/blinky_button/bsp_nucleo-c031c6.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example for STM32 NUCLEO-C031C6 // // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // // Copyright (C) 2005 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface #include "stm32c0xx.h" // CMSIS-compliant header file for the MCU used // add other drivers if necessary... // Local-scope defines ------------------------------------------------------- namespace { DBC_MODULE_NAME("bsp_nucleo-c031c6") // for DBC assertions in this module } // unnamed workspace // test pins on GPIO PA #define TST1_PIN 7U #define TST2_PIN 6U #define TST3_PIN 4U #define TST4_PIN 1U #define TST5_PIN 0U #define TST6_PIN 5U /* LED L4-Green */ // buttons on GPIO PC #define B1_PIN 13U // ISRs used in the application ============================================== extern "C" { void SysTick_Handler(void); // prototype void SysTick_Handler(void) { // system clock tick ISR BSP::d1on(); SST::TimeEvt::tick(); // get state of the user button // Perform the debouncing of buttons. The algorithm for debouncing // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle // and Michael Barr, page 71. // static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = ~GPIOC->IDR; // read GPIO PortC uint32_t tmp = buttons.depressed; // save the debounced depressed buttons.depressed |= (buttons.previous & current); // set depressed buttons.depressed &= (buttons.previous | current); // clear released buttons.previous = current; // update the history tmp ^= buttons.depressed; // changed debounced depressed if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? if ((buttons.depressed & (1U << B1_PIN)) != 0U) { // depressed? // immutable button-press event static App::ButtonWorkEvt const pressEvt = { { App::BUTTON_PRESSED_SIG }, 60U }; // immutable forward-press event static App::ButtonWorkEvt const fPressEvt = { { App::FORWARD_PRESSED_SIG }, 60U }; App::AO_Button2a->post(&fPressEvt.super); App::AO_Button2a->post(&pressEvt.super); } else { // B1 is released // immutable button-release event static App::ButtonWorkEvt const releaseEvt = { { App::BUTTON_RELEASED_SIG }, 80U }; // immutable forward-release event static App::ButtonWorkEvt const fReleaseEvt = { { App::FORWARD_RELEASED_SIG }, 80U }; App::AO_Button2a->post(&fReleaseEvt.super); App::AO_Button2a->post(&releaseEvt.super); } } BSP::d1off(); } // Assertion handler ========================================================= void DBC_fault_handler(char const * const module, int const label) { // // NOTE: add here your application-specific error handling // (void)module; (void)label; // set PRIMASK to disable interrupts and stop SST right here __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { // keep blinking LED2 BSP::d6on(); // turn LED2 on uint32_t volatile ctr; for (ctr = 10000U; ctr > 0U; --ctr) { } BSP::d6off(); // turn LED2 off for (ctr = 10000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } //............................................................................ void assert_failed(char const * const module, int const label);// prototype void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } // SST task activations ====================================================== // preprocessor switch to choose between regular and reserved IRQs #define REGULAR_IRQS #ifdef REGULAR_IRQS // repurpose regular IRQs for SST Tasks // prototypes void TIM3_IRQHandler(void); void TIM14_IRQHandler(void); void TIM16_IRQHandler(void); void TIM17_IRQHandler(void); void TIM3_IRQHandler(void) { App::AO_Blinky3->activate(); } void TIM14_IRQHandler(void) { App::AO_Button2b->activate(); } void TIM16_IRQHandler(void) { App::AO_Button2a->activate(); } void TIM17_IRQHandler(void) { App::AO_Blinky1->activate(); } #else // use reserved IRQs for SST Tasks // prototypes void Reserved1_IRQHandler(void); void Reserved8_IRQHandler(void); void Reserved15_IRQHandler(void); void Reserved17_IRQHandler(void); // use reserved IRQs for SST Tasks void Reserved1_IRQHandler(void) { App::AO_Blinky3->activate(); } void Reserved8_IRQHandler(void) { App::AO_Button2b->activate(); } void Reserved15_IRQHandler(void) { App::AO_Button2a->activate(); } void Reserved17_IRQHandler(void) { App::AO_Blinky1->activate(); } #endif } // extern "C" namespace BSP { // BSP functions ============================================================= void init(void) { // Configure the MPU to prevent NULL-pointer dereferencing // see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu // MPU->RBAR = 0x0U // base address (NULL) | MPU_RBAR_VALID_Msk // valid region | (MPU_RBAR_REGION_Msk & 7U); // region #7 MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region | (0x0U << MPU_RASR_AP_Pos) // no-access region | MPU_RASR_ENABLE_Msk; // region enable MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region | MPU_CTRL_ENABLE_Msk; // enable the MPU __ISB(); __DSB(); // assign IRQs to tasks. NOTE: critical for SST... #ifdef REGULAR_IRQS // repurpose regular IRQs for SST Tasks App::AO_Blinky3->setIRQ (TIM3_IRQn); App::AO_Button2b->setIRQ(TIM14_IRQn); App::AO_Button2a->setIRQ(TIM16_IRQn); App::AO_Blinky1->setIRQ (TIM17_IRQn); #else // use reserved IRQs for SST Tasks App::AO_Blinky3->setIRQ (1U); App::AO_Button2b->setIRQ(8U); App::AO_Button2a->setIRQ(15U); App::AO_Blinky1->setIRQ (17U); #endif // enable GPIO port PA clock RCC->IOPENR |= (1U << 0U); // set all used GPIOA pins as push-pull output, no pull-up, pull-down GPIOA->MODER &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); GPIOA->MODER |= ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); GPIOA->OTYPER &= ~((1U << TST1_PIN) | (1U << TST2_PIN) | (1U << TST3_PIN) | (1U << TST4_PIN) | (1U << TST5_PIN) | (1U << TST6_PIN)); GPIOA->OSPEEDR &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); GPIOA->OSPEEDR |= ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); GPIOA->PUPDR &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); // enable GPIOC clock port for the Button B1 RCC->IOPENR |= (1U << 2U); // configure Button B1 pin on GPIOC as input, no pull-up, pull-down GPIOC->MODER &= ~(3U << 2U*B1_PIN); GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); } //............................................................................ void d1on(void) { GPIOA->BSRR = (1U << TST1_PIN); } void d1off(void) { GPIOA->BSRR = (1U << (TST1_PIN + 16U)); } //............................................................................ void d2on(void) { GPIOA->BSRR = (1U << TST2_PIN); } void d2off(void) { GPIOA->BSRR = (1U << (TST2_PIN + 16U)); } //............................................................................ void d3on(void) { GPIOA->BSRR = (1U << TST3_PIN); } void d3off(void) { GPIOA->BSRR = (1U << (TST3_PIN + 16U)); } //............................................................................ void d4on(void) { GPIOA->BSRR = (1U << TST4_PIN); } void d4off(void) { GPIOA->BSRR = (1U << (TST4_PIN + 16U)); } //............................................................................ void d5on(void) { GPIOA->BSRR = (1U << TST5_PIN); } void d5off(void) { GPIOA->BSRR = (1U << (TST5_PIN + 16U)); } //............................................................................ void d6on(void) { GPIOA->BSRR = (1U << TST6_PIN); } // LD4 void d6off(void) { GPIOA->BSRR = (1U << (TST6_PIN + 16U)); } //............................................................................ SST::Evt const *getWorkEvtBlinky1(uint8_t num) { // immutable work events for Blinky1 static App::BlinkyWorkEvt const workBlinky1[] = { { { App::BLINKY_WORK_SIG }, 40U, 5U }, { { App::BLINKY_WORK_SIG }, 30U, 7U } }; DBC_REQUIRE(500, num < ARRAY_NELEM(workBlinky1)); // num must be in range return &workBlinky1[num].super; } //............................................................................ SST::Evt const *getWorkEvtBlinky3(uint8_t num) { // immutable work events for Blinky3 static App::BlinkyWorkEvt const workBlinky3[] = { { { App::BLINKY_WORK_SIG }, 20U, 5U }, { { App::BLINKY_WORK_SIG }, 10U, 3U } }; DBC_REQUIRE(600, num < ARRAY_NELEM(workBlinky3)); // num must be in range return &workBlinky3[num].super; } } // namespace BSP // SST callbacks ============================================================= namespace SST { void onStart(void) { SystemCoreClockUpdate(); // set up the SysTick timer to fire at BSP::TICKS_PER_SEC rate SysTick_Config((SystemCoreClock / BSP::TICKS_PER_SEC) + 1U); // set priorities of ISRs used in the system NVIC_SetPriority(SysTick_IRQn, 0U); // ... } //............................................................................ void onIdle(void) { BSP::d6on(); // turn LED2 on #ifdef NDEBUG // Put the CPU and peripherals to the low-power mode. // you might need to customize the clock management for your application, // see the datasheet for your particular Cortex-M MCU. // BSP::d6off(); // turn LED2 off __WFI(); // Wait-For-Interrupt BSP::d6on(); // turn LED2 on #endif BSP::d6off(); // turn LED2 off } } // namespace SST ================================================ FILE: sst_cpp/examples/blinky_button/bsp_nucleo-h743zi.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example for STM32 NUCLEO-H74cZI // // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // // Copyright (C) 2005 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface #include "stm32h743xx.h" // CMSIS-compliant header file for the MCU used #include // to exercise the FPU // add other drivers if necessary... // Local-scope defines ------------------------------------------------------- namespace { DBC_MODULE_NAME("bsp_nucleo-h743zi") // for DBC assertions in this module } // unnamed workspace // test pins on GPIO PB #define TST1_PIN 0U /* PB.0 LED1-Green */ #define TST2_PIN 14U /* PB.14 LED3-Red */ #define TST3_PIN 4U #define TST4_PIN 5U #define TST5_PIN 6U #define TST6_PIN 7U /* PB.7 LED2-Blue */ // buttons on GPIO PC #define B1_PIN 13U // ISRs used in the application ============================================== extern "C" { void SysTick_Handler(void) { // system clock tick ISR BSP::d1on(); SST::TimeEvt::tick(); // get state of the user button // Perform the debouncing of buttons. The algorithm for debouncing // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle // and Michael Barr, page 71. // static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = GPIOC->IDR; // read GPIO PortC uint32_t tmp = buttons.depressed; // save the debounced depressed buttons.depressed |= (buttons.previous & current); // set depressed buttons.depressed &= (buttons.previous | current); // clear released buttons.previous = current; // update the history tmp ^= buttons.depressed; // changed debounced depressed if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? if ((buttons.depressed & (1U << B1_PIN)) != 0U) { // depressed? // immutable button-press event static App::ButtonWorkEvt const pressEvt = { { App::BUTTON_PRESSED_SIG }, 60U }; // immutable forward-press event static App::ButtonWorkEvt const fPressEvt = { { App::FORWARD_PRESSED_SIG }, 60U }; App::AO_Button2a->post(&fPressEvt.super); App::AO_Button2a->post(&pressEvt.super); } else { // B1 is released // immutable button-release event static App::ButtonWorkEvt const releaseEvt = { { App::BUTTON_RELEASED_SIG }, 80U }; // immutable forward-release event static App::ButtonWorkEvt const fReleaseEvt = { { App::FORWARD_RELEASED_SIG }, 80U }; App::AO_Button2a->post(&fReleaseEvt.super); App::AO_Button2a->post(&releaseEvt.super); } } BSP::d1off(); } // Assertion handler ========================================================= void DBC_fault_handler(char const * const module, int const label) { // // NOTE: add here your application-specific error handling // (void)module; (void)label; // set PRIMASK to disable interrupts and stop SST right here __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { // keep blinking LED2 BSP::d6on(); // turn LED2 on uint32_t volatile ctr; for (ctr = 1000000U; ctr > 0U; --ctr) { } BSP::d6off(); // turn LED2 off for (ctr = 1000000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } //............................................................................ void assert_failed(char const * const module, int const label);// prototype void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } // SST task activations ====================================================== // preprocessor switch to choose between regular and reserved IRQs #define REGULAR_IRQS #ifdef REGULAR_IRQS // repurpose regular IRQs for SST Tasks // prototypes void OTG_FS_EP1_OUT_IRQHandler(void); void OTG_FS_EP1_IN_IRQHandler(void); void OTG_FS_WKUP_IRQHandler(void); void OTG_FS_IRQHandler(void); void OTG_FS_EP1_OUT_IRQHandler(void) { App::AO_Blinky3->activate(); } void OTG_FS_EP1_IN_IRQHandler(void) { App::AO_Button2b->activate(); } void OTG_FS_WKUP_IRQHandler(void) { App::AO_Button2a->activate(); } void OTG_FS_IRQHandler(void) { App::AO_Blinky1->activate(); } #else // use reserved IRQs for SST Tasks // prototypes void Reserved42_IRQHandler(void); // prototype void Reserved64_IRQHandler(void); // prototype void Reserved65_IRQHandler(void); // prototype void Reserved66_IRQHandler(void); // prototype void Reserved42_IRQHandler(void) { App::AO_Blinky3->activate(); } void Reserved64_IRQHandler(void) { App::AO_Button2b->activate(); } void Reserved65_IRQHandler(void) { App::AO_Button2a->activate(); } void Reserved66_IRQHandler(void) { App::AO_Blinky1->activate(); } #endif } // extern "C" namespace BSP { // BSP functions ============================================================= void init(void) { // Configure the MPU to prevent NULL-pointer dereferencing // see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu // MPU->RBAR = 0x0U // base address (NULL) | MPU_RBAR_VALID_Msk // valid region | (MPU_RBAR_REGION_Msk & 7U); // region #7 MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region | (0x0U << MPU_RASR_AP_Pos) // no-access region | MPU_RASR_ENABLE_Msk; // region enable MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region | MPU_CTRL_ENABLE_Msk; // enable the MPU __ISB(); __DSB(); SCB_EnableICache(); // Enable I-Cache SCB_EnableDCache(); // Enable D-Cache // assign IRQs to tasks. NOTE: critical for SST... #ifdef REGULAR_IRQS // repurpose regular IRQs for SST Tasks App::AO_Blinky3->setIRQ(OTG_FS_EP1_OUT_IRQn); App::AO_Button2b->setIRQ(OTG_FS_EP1_IN_IRQn); App::AO_Button2a->setIRQ(OTG_FS_WKUP_IRQn); App::AO_Blinky1->setIRQ(OTG_FS_IRQn); #else // use reserved IRQs for SST Tasks App::AO_Blinky3->setIRQ(42U); App::AO_Button2b->setIRQ(64U); App::AO_Button2a->setIRQ(65U); App::AO_Blinky1->setIRQ(66U); #endif // enable GPIOB port clock for LEds and test pins RCC->AHB4ENR |= RCC_AHB4ENR_GPIOBEN; // set all used GPIOB pins as push-pull output, no pull-up, pull-down GPIOB->MODER &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); GPIOB->MODER |= ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); GPIOB->OTYPER &= ~((1U << TST1_PIN) | (1U << TST2_PIN) | (1U << TST3_PIN) | (1U << TST4_PIN) | (1U << TST5_PIN) | (1U << TST6_PIN)); GPIOB->PUPDR &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); // enable GPIOC clock port for the Button B1 RCC->AHB4ENR |= RCC_AHB4ENR_GPIOCEN; // configure Button B1 pin on GPIOC as input, no pull-up, pull-down GPIOC->MODER &= ~(3U << 2U*B1_PIN); GPIOC->PUPDR &= ~(GPIO_PUPDR_PUPD0 << 2U*B1_PIN); GPIOC->PUPDR |= (2U << 2U*B1_PIN); } //............................................................................ static void exerciseFPU(double x) { // exercise the double-precision FPU by calculating the identity: // sin(x)^2 + cos(x)^2 == 1.0 for any x // double tmp = pow(sin(x), 2.0) + pow(cos(x), 2.0); DBC_ENSURE(200, ((1.0 - 1e-4) < tmp) && (tmp < (1.0 + 1e-4))); } //............................................................................ void d1on(void) { // LED1-Green GPIOB->BSRR = (1U << TST1_PIN); // don't use the FPU in the ISR } void d1off(void) { GPIOB->BSRR = (1U << (TST1_PIN + 16U)); } //............................................................................ void d2on(void) { // LED3-Red GPIOB->BSRR = (1U << TST2_PIN); exerciseFPU(-1.2345); } void d2off(void) { GPIOB->BSRR = (1U << (TST2_PIN + 16U)); } //............................................................................ void d3on(void) { GPIOB->BSRR = (1U << TST3_PIN); exerciseFPU(-12.345); } void d3off(void) { GPIOB->BSRR = (1U << (TST3_PIN + 16U)); } //............................................................................ void d4on(void) { GPIOB->BSRR = (1U << TST4_PIN); exerciseFPU(3.456); } void d4off(void) { GPIOB->BSRR = (1U << (TST4_PIN + 16U)); } //............................................................................ void d5on(void) { GPIOB->BSRR = (1U << TST5_PIN); exerciseFPU(4.567); } void d5off(void) { GPIOB->BSRR = (1U << (TST5_PIN + 16U)); } //............................................................................ void d6on(void) { // LED2-Blue GPIOB->BSRR = (1U << TST6_PIN); exerciseFPU(1.2345); } void d6off(void) { GPIOB->BSRR = (1U << (TST6_PIN + 16U)); } //............................................................................ SST::Evt const *getWorkEvtBlinky1(uint8_t num) { // immutable work events for Blinky1 static App::BlinkyWorkEvt const workBlinky1[] = { { { App::BLINKY_WORK_SIG }, 40U, 5U }, { { App::BLINKY_WORK_SIG }, 30U, 7U } }; DBC_REQUIRE(500, num < ARRAY_NELEM(workBlinky1)); // num must be in range return &workBlinky1[num].super; } //............................................................................ SST::Evt const *getWorkEvtBlinky3(uint8_t num) { // immutable work events for Blinky3 static App::BlinkyWorkEvt const workBlinky3[] = { { { App::BLINKY_WORK_SIG }, 20U, 5U }, { { App::BLINKY_WORK_SIG }, 10U, 3U } }; DBC_REQUIRE(600, num < ARRAY_NELEM(workBlinky3)); // num must be in range return &workBlinky3[num].super; } } // namespace BSP // SST callbacks ============================================================= namespace SST { void onStart(void) { SystemCoreClockUpdate(); // set up the SysTick timer to fire at BSP::TICKS_PER_SEC rate SysTick_Config((SystemCoreClock / BSP::TICKS_PER_SEC) + 1U); // set priorities of ISRs used in the system NVIC_SetPriority(SysTick_IRQn, 0U); // ... } //............................................................................ void onIdle(void) { BSP::d6on(); // turn LED2 on #ifdef NDEBUG // Put the CPU and peripherals to the low-power mode. // you might need to customize the clock management for your application, // see the datasheet for your particular Cortex-M MCU. // BSP::d6off(); // turn LED2 off __WFI(); // Wait-For-Interrupt BSP::d6on(); // turn LED2 on #endif BSP::d6off(); // turn LED2 off } } // namespace SST ================================================ FILE: sst_cpp/examples/blinky_button/bsp_nucleo-l053r8.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example for STM32 NUCLEO-L053R8 // // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // // Copyright (C) 2005 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface #include "stm32l0xx.h" // CMSIS-compliant header file for the MCU used // add other drivers if necessary... // Local-scope defines ------------------------------------------------------- namespace { DBC_MODULE_NAME("bsp_nucleo-l053r8") // for DBC assertions in this module } // unnamed workspace // test pins on GPIO PA #define TST1_PIN 7U #define TST2_PIN 6U #define TST3_PIN 4U #define TST4_PIN 1U #define TST5_PIN 0U #define TST6_PIN 5U /* LED LD2-Green */ // buttons on GPIO PC #define B1_PIN 13U // ISRs used in the application ============================================== extern "C" { void SysTick_Handler(void); // prototype void SysTick_Handler(void) { // system clock tick ISR BSP::d1on(); SST::TimeEvt::tick(); // get state of the user button // Perform the debouncing of buttons. The algorithm for debouncing // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle // and Michael Barr, page 71. // static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; uint32_t current = ~GPIOC->IDR; // read GPIO PortC uint32_t tmp = buttons.depressed; // save the debounced depressed buttons.depressed |= (buttons.previous & current); // set depressed buttons.depressed &= (buttons.previous | current); // clear released buttons.previous = current; // update the history tmp ^= buttons.depressed; // changed debounced depressed if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? if ((buttons.depressed & (1U << B1_PIN)) != 0U) { // depressed? // immutable button-press event static App::ButtonWorkEvt const pressEvt = { { App::BUTTON_PRESSED_SIG }, 60U }; // immutable forward-press event static App::ButtonWorkEvt const fPressEvt = { { App::FORWARD_PRESSED_SIG }, 60U }; App::AO_Button2a->post(&fPressEvt.super); App::AO_Button2a->post(&pressEvt.super); } else { // B1 is released // immutable button-release event static App::ButtonWorkEvt const releaseEvt = { { App::BUTTON_RELEASED_SIG }, 80U }; // immutable forward-release event static App::ButtonWorkEvt const fReleaseEvt = { { App::FORWARD_RELEASED_SIG }, 80U }; App::AO_Button2a->post(&fReleaseEvt.super); App::AO_Button2a->post(&releaseEvt.super); } } BSP::d1off(); } // Assertion handler ========================================================= void DBC_fault_handler(char const * const module, int const label) { // // NOTE: add here your application-specific error handling // (void)module; (void)label; // set PRIMASK to disable interrupts and stop SST right here __asm volatile ("cpsid i"); #ifndef NDEBUG for (;;) { // keep blinking LED2 BSP::d6on(); // turn LED2 on uint32_t volatile ctr; for (ctr = 10000U; ctr > 0U; --ctr) { } BSP::d6off(); // turn LED2 off for (ctr = 10000U; ctr > 0U; --ctr) { } } #endif NVIC_SystemReset(); } //............................................................................ void assert_failed(char const * const module, int const label);// prototype void assert_failed(char const * const module, int const label) { DBC_fault_handler(module, label); } // SST task activations ====================================================== // preprocessor switch to choose between regular and reserved IRQs #define REGULAR_IRQS #ifdef REGULAR_IRQS // repurpose regular IRQs for SST Tasks // prototypes void PVD_IRQHandler(void); void RTC_IRQHandler(void); void TSC_IRQHandler(void); void I2C2_IRQHandler(void); void PVD_IRQHandler(void) { App::AO_Blinky3->activate(); } void RTC_IRQHandler(void) { App::AO_Button2b->activate(); } void TSC_IRQHandler(void) { App::AO_Button2a->activate(); } void I2C2_IRQHandler(void) { App::AO_Blinky1->activate(); } #else // use reserved IRQs for SST Tasks // prototypes void Reserved14_IRQHandler(void); // prototype void Reserved16_IRQHandler(void); // prototype void Reserved18_IRQHandler(void); // prototype void Reserved19_IRQHandler(void); // prototype // use reserved IRQs for SST Tasks void Reserved14_IRQHandler(void) { App::AO_Blinky3->activate(); } void Reserved16_IRQHandler(void) { App::AO_Button2b->activate(); } void Reserved18_IRQHandler(void) { App::AO_Button2a->activate(); } void Reserved19_IRQHandler(void) { App::AO_Blinky1->activate(); } #endif } // extern "C" namespace BSP { // BSP functions ============================================================= void init(void) { // Configure the MPU to prevent NULL-pointer dereferencing // see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu // MPU->RBAR = 0x0U // base address (NULL) | MPU_RBAR_VALID_Msk // valid region | (MPU_RBAR_REGION_Msk & 7U); // region #7 MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region | (0x0U << MPU_RASR_AP_Pos) // no-access region | MPU_RASR_ENABLE_Msk; // region enable MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region | MPU_CTRL_ENABLE_Msk; // enable the MPU __ISB(); __DSB(); // assign IRQs to tasks. NOTE: critical for SST... #ifdef REGULAR_IRQS // repurpose regular IRQs for SST Tasks App::AO_Blinky3->setIRQ (PVD_IRQn); App::AO_Button2b->setIRQ(RTC_IRQn); App::AO_Button2a->setIRQ(TSC_IRQn); App::AO_Blinky1->setIRQ (I2C2_IRQn); #else // use reserved IRQs for SST Tasks App::AO_Blinky3->setIRQ (14U); App::AO_Button2b->setIRQ(16U); App::AO_Button2a->setIRQ(18U); App::AO_Blinky1->setIRQ (19U); #endif // enable GPIO port PA clock RCC->IOPENR |= (1U << 0U); // set all used GPIOA pins as push-pull output, no pull-up, pull-down GPIOA->MODER &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); GPIOA->MODER |= ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); GPIOA->OTYPER &= ~((1U << TST1_PIN) | (1U << TST2_PIN) | (1U << TST3_PIN) | (1U << TST4_PIN) | (1U << TST5_PIN) | (1U << TST6_PIN)); GPIOA->PUPDR &= ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); // enable GPIOC clock port for the Button B1 RCC->IOPENR |= (1U << 2U); // configure Button B1 pin on GPIOC as input, no pull-up, pull-down GPIOC->MODER &= ~(3U << 2U*B1_PIN); GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); } //............................................................................ void d1on(void) { GPIOA->BSRR = (1U << TST1_PIN); } void d1off(void) { GPIOA->BSRR = (1U << (TST1_PIN + 16U)); } //............................................................................ void d2on(void) { GPIOA->BSRR = (1U << TST2_PIN); } void d2off(void) { GPIOA->BSRR = (1U << (TST2_PIN + 16U)); } //............................................................................ void d3on(void) { GPIOA->BSRR = (1U << TST3_PIN); } void d3off(void) { GPIOA->BSRR = (1U << (TST3_PIN + 16U)); } //............................................................................ void d4on(void) { GPIOA->BSRR = (1U << TST4_PIN); } void d4off(void) { GPIOA->BSRR = (1U << (TST4_PIN + 16U)); } //............................................................................ void d5on(void) { GPIOA->BSRR = (1U << TST5_PIN); } void d5off(void) { GPIOA->BSRR = (1U << (TST5_PIN + 16U)); } //............................................................................ void d6on(void) { GPIOA->BSRR = (1U << TST6_PIN); } // LED2 void d6off(void) { GPIOA->BSRR = (1U << (TST6_PIN + 16U)); } //............................................................................ SST::Evt const *getWorkEvtBlinky1(uint8_t num) { // immutable work events for Blinky1 static App::BlinkyWorkEvt const workBlinky1[] = { { { App::BLINKY_WORK_SIG }, 40U, 5U }, { { App::BLINKY_WORK_SIG }, 30U, 7U } }; DBC_REQUIRE(500, num < ARRAY_NELEM(workBlinky1)); // num must be in range return &workBlinky1[num].super; } //............................................................................ SST::Evt const *getWorkEvtBlinky3(uint8_t num) { // immutable work events for Blinky3 static App::BlinkyWorkEvt const workBlinky3[] = { { { App::BLINKY_WORK_SIG }, 20U, 5U }, { { App::BLINKY_WORK_SIG }, 10U, 3U } }; DBC_REQUIRE(600, num < ARRAY_NELEM(workBlinky3)); // num must be in range return &workBlinky3[num].super; } } // namespace BSP // SST callbacks ============================================================= namespace SST { void onStart(void) { SystemCoreClockUpdate(); // set up the SysTick timer to fire at BSP::TICKS_PER_SEC rate SysTick_Config((SystemCoreClock / BSP::TICKS_PER_SEC) + 1U); // set priorities of ISRs used in the system NVIC_SetPriority(SysTick_IRQn, 0U); // ... } //............................................................................ void onIdle(void) { BSP::d6on(); // turn LED2 on #ifdef NDEBUG // Put the CPU and peripherals to the low-power mode. // you might need to customize the clock management for your application, // see the datasheet for your particular Cortex-M MCU. // BSP::d6off(); // turn LED2 off __WFI(); // Wait-For-Interrupt BSP::d6on(); // turn LED2 on #endif BSP::d6off(); // turn LED2 off } } // namespace SST ================================================ FILE: sst_cpp/examples/blinky_button/button2a.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface namespace { DBC_MODULE_NAME("button2a") // for DBC assertions in this module } // unnamed namespace namespace App { //............................................................................ class Button2a : public SST::Task { // add internal variables for this AO... public: static Button2a inst; void init(SST::Evt const * const ie) override; void dispatch(SST::Evt const * const e) override; }; //............................................................................ Button2a Button2a::inst; // the Button2a instance SST::Task * const AO_Button2a = &Button2a::inst; // opaque AO pointer //............................................................................ void Button2a::init(SST::Evt const * const /*ie*/) { } //............................................................................ void Button2a::dispatch(SST::Evt const * const e) { switch (e->sig) { case BUTTON_PRESSED_SIG: { BSP::d4on(); // Button2a --> Blinky1 AO_Blinky1->post(BSP::getWorkEvtBlinky1(1U)); BSP::d4off(); for (std::uint16_t i = SST::evt_downcast(e)->toggles; i > 0U; --i) { BSP::d4on(); BSP::d4off(); } break; } case FORWARD_PRESSED_SIG: { BSP::d4on(); // immutable event can be forwarded to another Task AO_Button2b->post(e); // Button2a --> Button2b BSP::d4off(); break; } case BUTTON_RELEASED_SIG: { static BlinkyWorkEvt const bw2evt = { { BLINKY_WORK_SIG }, 30U, 7U }; AO_Blinky1->post(&bw2evt.super); // Button2b --> Blinky1 for (uint16_t i = SST::evt_downcast(e)->toggles; i > 0U; --i) { BSP::d4on(); BSP::d4off(); } break; } case FORWARD_RELEASED_SIG: { BSP::d4on(); // immutable event can be forwarded to another Task AO_Button2b->post(e); // Button2a --> Button2b BSP::d4off(); break; } default: { DBC_ERROR(500); // unexpected event break; } } } } // namespace App ================================================ FILE: sst_cpp/examples/blinky_button/button2b.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface namespace { DBC_MODULE_NAME("button2b") // for DBC assertions in this module } // unnamed namespace namespace App { //............................................................................ class Button2b : public SST::Task { // add internal variables for this AO... public: static Button2b inst; void init(SST::Evt const * const ie) override; void dispatch(SST::Evt const * const e) override; }; //............................................................................ Button2b Button2b::inst; // the Button2b instance SST::Task * const AO_Button2b = &Button2b::inst; // opaque AO pointer //............................................................................ void Button2b::init(SST::Evt const * const /*ie*/) { } //............................................................................ void Button2b::dispatch(SST::Evt const * const e) { switch (e->sig) { case FORWARD_PRESSED_SIG: { BSP::d3on(); // Button2b --> Blinky3 AO_Blinky3->post(BSP::getWorkEvtBlinky3(1U)); BSP::d3off(); for (std::uint16_t i = SST::evt_downcast(e)->toggles; i > 0U; --i) { BSP::d3on(); BSP::d3off(); } break; } case FORWARD_RELEASED_SIG: { BSP::d3on(); // Button2b --> Blinky3 AO_Blinky3->post(BSP::getWorkEvtBlinky3(0U)); BSP::d3off(); for (uint16_t i = SST::evt_downcast(e)->toggles; i > 0U; --i) { BSP::d3on(); BSP::d3off(); } break; } default: { DBC_ERROR(500); /* unexpected event */ break; } } } } // namespace App ================================================ FILE: sst_cpp/examples/blinky_button/gnu/ek-tm4c123gxl.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST/C++) on TM4C123GXL, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-01-25 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f ek-tm4c123gxl.mak # make -f ek-tm4c123gxl.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky_button TARGET := ek-tm4c123gxl #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ system_TM4C123GH6PM.c \ startup_TM4C123GH6PM.c # C++ source files CPP_SRCS := \ sst.cpp \ sst_port.cpp \ main.cpp \ blinky1.cpp \ blinky3.cpp \ button2a.cpp \ button2b.cpp \ bsp_ek-tm4c123gxl.cpp LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := -DTARGET_IS_TM4C123_RB1 # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m4 ARM_FPU := -mfpu=vfp FLOAT_ABI := -mfloat-abi=softfp #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-g++ BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst_cpp/examples/blinky_button/gnu/flash_ek-tm4c123gxl.bat ================================================ ::============================================================================ :: Batch file to program the flash of EK-TM4C123GXL :: :: NOTE: requires the LMFlash programmer (included in QTools for Windows) :: @echo off setlocal @echo Load a given binary file to the flash of EK-TM4C123GXL @echo usage: flash binary-file @echo example: flash dbg\blinky-qk.bin ::---------------------------------------------------------------------------- :: NOTE: The following symbol LMFLASH assumes that LMFlash.exe can :: be found on the PATH. You might need to adjust this symbol to the :: location of the LMFlash utility on your machine :: set LMFLASH=LMFlash.exe if ["%~1"]==[""] ( @echo The binary file missing @goto end ) if not exist %~s1 ( @echo The binary file '%1' does not exist @goto end ) %LMFLASH% -q ek-tm4c123gxl -e -v -r %1 :end endlocal ================================================ FILE: sst_cpp/examples/blinky_button/gnu/nucleo-c031c6.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST/C) on NUCLEO-C031C6, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-02-01 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f nucleo-c031c6.mak # make -f nucleo-c031c6.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky_button TARGET := nucleo-c031c6 #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ system_stm32c0xx.c \ startup_stm32c031xx.c # C++ source files CPP_SRCS := \ sst.cpp \ sst_port.cpp \ main.cpp \ blinky1.cpp \ blinky3.cpp \ button2a.cpp \ button2b.cpp \ bsp_nucleo-c031c6.cpp LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := -DSTM32C031xx # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m0plus ARM_FPU := FLOAT_ABI := #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-g++ BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst_cpp/examples/blinky_button/gnu/nucleo-h743zi.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST/C++) on NUCLEO-H743ZI, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-01-22 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f nucleo-h743zi.mak # make -f nucleo-h743zi.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky_button TARGET := nucleo-h743zi #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ startup_stm32h743xx.c \ system_stm32h7xx.c # C++ source files CPP_SRCS := \ sst.cpp \ sst_port.cpp \ main.cpp \ blinky1.cpp \ blinky3.cpp \ button2a.cpp \ button2b.cpp \ bsp_nucleo-h743zi.cpp LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := -DSTM32H743xx # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m7 ARM_FPU := -mfpu=fpv5-d16 FLOAT_ABI := -mfloat-abi=softfp #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-g++ BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst_cpp/examples/blinky_button/gnu/nucleo-l053r8.mak ================================================ ############################################################################## # Makefile for Super-Simple Tasker (SST/C++) on NUCLEO-L053R8, GNU-ARM # Last Updated for Version: 2.0.0 # Date of the Last Update: 2023-01-22 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # # Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. ############################################################################## # examples of invoking this Makefile: # make -f nucleo-l053r8.mak # make -f nucleo-l053r8.mak clean # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: # https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project and target names # PROJECT := blinky_button TARGET := nucleo-l053r8 #----------------------------------------------------------------------------- # project directories # SST_DIR := ../../.. SST_PORT_DIR := $(SST_DIR)/ports/arm-cm CMSIS_DIR := ../../../../3rd_party/CMSIS TARGET_DIR := ../../../../3rd_party/$(TARGET) # list of all source directories used by this project VPATH = .. \ $(SST_DIR)/src \ $(SST_PORT_DIR) \ $(TARGET_DIR) \ $(TARGET_DIR)/gnu \ # list of all include directories needed by this project INCLUDES = -I. \ -I$(SST_DIR)/../include \ -I$(SST_PORT_DIR) \ -I$(CMSIS_DIR)/Include \ -I$(TARGET_DIR) #----------------------------------------------------------------------------- # project files # # assembler source files ASM_SRCS := # C source files C_SRCS := \ system_stm32l0xx.c \ startup_stm32l053xx.c # C++ source files CPP_SRCS := \ sst.cpp \ sst_port.cpp \ main.cpp \ blinky1.cpp \ blinky3.cpp \ button2a.cpp \ button2b.cpp \ bsp_nucleo-l053r8.cpp LD_SCRIPT := $(TARGET_DIR)/gnu/$(TARGET).ld OUTPUT := $(PROJECT) LIB_DIRS := LIBS := # defines DEFINES := # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # ARM_CPU := -mcpu=cortex-m0plus ARM_FPU := FLOAT_ABI := #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) # see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads # ifeq ($(GNU_ARM),) GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi endif # make sure that the GNU-ARM toolset exists... ifeq ("$(wildcard $(GNU_ARM))","") $(error GNU_ARM toolset not found. Please adjust the Makefile) endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-g++ BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy ############################################################################## # Typically you should not need to change anything below this line # basic utilities (included in QTools for Windows), see: # https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- # build options # # combine all the soruces... C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c99 -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -std=c++11 -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) # create $(BIN_DIR) if it does not exist ifeq ("$(wildcard $(BIN_DIR))","") $(shell $(MKDIR) $(BIN_DIR)) endif #----------------------------------------------------------------------------- # rules # .PHONY : run norun flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) norun : all else all : $(TARGET_BIN) run endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(LINK) $(LINKFLAGS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ $(BIN_DIR)/%.o : %.s $(AS) $(ASFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ .PHONY : clean show # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) @echo DEFINES = $(DEFINES) @echo ASM_FPU = $(ASM_FPU) @echo ASM_SRCS = $(ASM_SRCS) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo TARGET_ELF = $(TARGET_ELF) ================================================ FILE: sst_cpp/examples/blinky_button/iar/ek-tm4c123gxl.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst_cpp/examples/blinky_button/iar/ek-tm4c123gxl.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Application $PROJ_DIR$\..\blinky1.cpp $PROJ_DIR$\..\blinky3.cpp $PROJ_DIR$\..\bsp.hpp $PROJ_DIR$\..\bsp_ek-tm4c123gxl.cpp $PROJ_DIR$\..\button2a.cpp $PROJ_DIR$\..\button2b.cpp $PROJ_DIR$\..\main.cpp ek-tm4c123gxl $PROJ_DIR$\..\..\..\..\3rd_party\ek-tm4c123gxl\iar\startup_TM4C123GH6PM.s $PROJ_DIR$\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c $PROJ_DIR$\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h sst $PROJ_DIR$\..\..\..\src\sst.cpp sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.cpp $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.hpp ================================================ FILE: sst_cpp/examples/blinky_button/iar/ek-tm4c123gxl.eww ================================================ $WS_DIR$\ek-tm4c123gxl.ewp ================================================ FILE: sst_cpp/examples/blinky_button/iar/nucleo-c031c6.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst_cpp/examples/blinky_button/iar/nucleo-c031c6.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Debug Application $PROJ_DIR$\..\blinky1.cpp $PROJ_DIR$\..\blinky3.cpp $PROJ_DIR$\..\blinky_button.hpp $PROJ_DIR$\..\bsp.hpp $PROJ_DIR$\..\bsp_nucleo-c031c6.cpp $PROJ_DIR$\..\button2a.cpp $PROJ_DIR$\..\button2b.cpp $PROJ_DIR$\..\main.cpp nucleo-c031c6 $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-c031c6\iar\startup_stm32c031xx.s $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.h sst $PROJ_DIR$\..\..\..\src\sst.cpp sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.cpp $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.hpp ================================================ FILE: sst_cpp/examples/blinky_button/iar/nucleo-c031c6.eww ================================================ $WS_DIR$\nucleo-c031c6.ewp ================================================ FILE: sst_cpp/examples/blinky_button/iar/nucleo-h743zi.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst_cpp/examples/blinky_button/iar/nucleo-h743zi.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Debug Application $PROJ_DIR$\..\blinky1.cpp $PROJ_DIR$\..\blinky3.cpp $PROJ_DIR$\..\blinky_button.hpp $PROJ_DIR$\..\bsp.hpp $PROJ_DIR$\..\bsp_nucleo-h743zi.cpp $PROJ_DIR$\..\button2a.cpp $PROJ_DIR$\..\button2b.cpp $PROJ_DIR$\..\main.cpp nucleo-h743zi $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-h743zi\iar\startup_stm32h743xx.s $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-h743zi\stm32h743xx.h $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-h743zi\system_stm32h7xx.c sst $PROJ_DIR$\..\..\..\src\sst.cpp sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.cpp $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.hpp ================================================ FILE: sst_cpp/examples/blinky_button/iar/nucleo-h743zi.eww ================================================ $WS_DIR$\nucleo-h743zi.ewp ================================================ FILE: sst_cpp/examples/blinky_button/iar/nucleo-l053r8.ewd ================================================ 3 Debug ARM 1 C-SPY 2 32 1 1 ARMSIM_ID 2 1 1 1 CADI_ID 2 0 1 1 CMSISDAP_ID 2 4 1 1 GDBSERVER_ID 2 0 1 1 IJET_ID 2 9 1 1 JLINK_ID 2 16 1 1 LMIFTDI_ID 2 3 1 1 NULINK_ID 2 0 1 1 PEMICRO_ID 2 3 1 1 STLINK_ID 2 8 1 1 THIRDPARTY_ID 2 0 1 1 TIFET_ID 2 1 1 1 XDS100_ID 2 9 1 1 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 ================================================ FILE: sst_cpp/examples/blinky_button/iar/nucleo-l053r8.ewp ================================================ 3 Debug ARM 1 General 3 35 1 1 ICCARM 2 37 1 1 AARM 2 11 1 1 OBJCOPY 0 1 1 1 CUSTOM 3 1 inputOutputBased BUILDACTION 1 ILINK 0 27 1 1 IARCHIVE 0 0 1 1 Coder 0 Debug Application $PROJ_DIR$\..\blinky1.cpp $PROJ_DIR$\..\blinky3.cpp $PROJ_DIR$\..\blinky_button.hpp $PROJ_DIR$\..\bsp.hpp $PROJ_DIR$\..\bsp_nucleo-l053r8.cpp $PROJ_DIR$\..\button2a.cpp $PROJ_DIR$\..\button2b.cpp $PROJ_DIR$\..\main.cpp nucleo-l053r8 $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\iar\startup_stm32l053xx.s $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h $PROJ_DIR$\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c sst $PROJ_DIR$\..\..\..\src\sst.cpp sst_port $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.cpp $PROJ_DIR$\..\..\..\ports\arm-cm\sst_port.hpp ================================================ FILE: sst_cpp/examples/blinky_button/iar/nucleo-l053r8.eww ================================================ $WS_DIR$\nucleo-l053r8.ewp ================================================ FILE: sst_cpp/examples/blinky_button/main.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) Example // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // SST framework #include "bsp.hpp" // Board Support Package interface #include "blinky_button.hpp" // application shared interface //............................................................................ int main() { SST::init(); // initialize the SST kernel BSP::init(); // initialize the Board Support Package // instantiate and start all SST tasks... static SST::Evt const *blinky1QSto[10]; // Event queue storage App::AO_Blinky1->start( 1U, // SST-priority blinky1QSto, // storage for the AO's queue ARRAY_NELEM(blinky1QSto), // queue length BSP::getWorkEvtBlinky1(0U)); // initialization event static SST::Evt const *button2aQSto[8]; // Event queue storage App::AO_Button2a->start( 2U, // SST-priority button2aQSto, // storage for the AO's queue ARRAY_NELEM(button2aQSto), // queue length nullptr); // initialization event static SST::Evt const *button2bQSto[6]; // Event queue storage App::AO_Button2b->start( 2U, // SST-priority button2bQSto, // storage for the AO's queue ARRAY_NELEM(button2bQSto), // queue length nullptr); // initialization event static SST::Evt const *blinky3QSto[4]; // Event queue storage App::AO_Blinky3->start( 3U, // SST-priority blinky3QSto, // storage for the AO's queue ARRAY_NELEM(blinky3QSto), // queue length BSP::getWorkEvtBlinky3(0U)); // initialization event return SST::Task::run(); // run the SST tasks // NOTE: in embedded systems SST::Task::run() should not return } ================================================ FILE: sst_cpp/ports/arm-cm/sst_port.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) port to ARM Cortex-M // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // Super-Simple Tasker (SST/C++) #include "dbc_assert.h" // Design By Contract (DBC) assertions #define NVIC_PEND ((uint32_t volatile *)0xE000E200U) #define NVIC_EN ((uint32_t volatile *)0xE000E100U) #define NVIC_IP ((uint32_t volatile *)0xE000E400U) #define SCB_SYSPRI ((uint32_t volatile *)0xE000ED14U) #define SCB_AIRCR *((uint32_t volatile *)0xE000ED0CU) #define FPU_FPCCR *((uint32_t volatile *)0xE000EF34U) //............................................................................ namespace { // unnamed namespace DBC_MODULE_NAME("sst_port") // for DBC assertions in this module // # of unused interrupt priority bits in NVIC static std::uint32_t nvic_prio_shift; } // unnamed namespace namespace SST { // SST kernel facilities ----------------------------------------------------- void init(void) { // determine number of NVIC priority bits by writing 0xFF to the // NIVIC IP register for PendSV and then reading back the result, // which has only the implemented bits set. std::uint32_t tmp = SCB_SYSPRI[3]; SCB_SYSPRI[3] |= (0xFFU << 16U); // write 0xFF to PendSV prio uint32_t prio = ((SCB_SYSPRI[3] >> 16U) & 0xFFU); // read back SCB_SYSPRI[3] = tmp; // restore the original PendSV prio for (tmp = 0U; tmp < 8U; ++tmp) { if ((prio & (1U << tmp)) != 0U) { break; } } nvic_prio_shift = tmp; #if (__ARM_FP != 0) // configure the FPU for SST FPU_FPCCR |= (1U << 30U) // automatic FPU state preservation (ASPEN) | (1U << 31U); // lazy stacking (LSPEN) #endif } //............................................................................ void start(void) { // Set the NVIC priority grouping to default 0 // // NOTE: // Typically the SST port to ARM Cortex-M should waste no NVIC priority // bits for grouping. This code ensures this setting, but priority // grouping can be still overridden in the application-specific // callback SST_onStart(). // std::uint32_t tmp = SCB_AIRCR; // clear the key bits 31:16 and priority grouping bits 10:8 tmp &= ~((0xFFFFU << 16U) | (0x7U << 8U)); SCB_AIRCR = (0x05FAU << 16U) | tmp; } // SST Task facilities ------------------------------------------------------- void Task::setPrio(TaskPrio prio) noexcept { //! @pre //! - the IRQ number must be already set //! - the priority must fit in the NVIC DBC_REQUIRE(200, (m_nvic_irq != 0U) && (prio <= (0xFFU >> nvic_prio_shift))); // convert the SST direct priority (1,2,..) to NVIC priority... std::uint32_t irq_prio = ((0xFFU >> nvic_prio_shift) + 1U - prio) << nvic_prio_shift; SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); // set the Task priority of the associated IRQ uint32_t tmp = NVIC_IP[m_nvic_irq >> 2U]; tmp &= ~(0xFFU << ((m_nvic_irq & 3U) << 3U)); tmp |= (irq_prio << ((m_nvic_irq & 3U) << 3U)); NVIC_IP[m_nvic_irq >> 2U] = tmp; // enable the IRQ associated with the Task NVIC_EN[m_nvic_irq >> 5U] = (1U << (m_nvic_irq & 0x1FU)); SST_PORT_CRIT_EXIT(); // store the address of NVIC_PEND address and the IRQ bit m_nvic_pend = &NVIC_PEND[m_nvic_irq >> 5U]; m_nvic_irq = (1U << (m_nvic_irq & 0x1FU)); } //............................................................................ void Task::activate(void) { //! @pre the queue must have some events DBC_REQUIRE(300, m_nUsed > 0U); // get the event out of the queue // NOTE: no critical section because me->tail is accessed only // from this task Evt const *e = m_qBuf[m_tail]; if (m_tail == 0U) { // need to wrap the tail? m_tail = m_end; // wrap around } else { --m_tail; } SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); // some events still present in the queue? if ((--m_nUsed) > 0U) { *m_nvic_pend = m_nvic_irq; // <=== pend the associated IRQ } SST_PORT_CRIT_EXIT(); // dispatch the received event to this task dispatch(e); // virtual call // TBD: implement event recycling } //............................................................................ void Task::setIRQ(std::uint32_t irq) noexcept { m_nvic_irq = irq; } //............................................................................ LockKey Task::lock(TaskPrio ceiling) { #if (__ARM_ARCH == 6) // ARMv6-M? // NOTE: // ARMv6-M (Cortex-M0/M0+/M1) do NOT support the BASEPRI register // and simple selective scheduler locking is not possible. // Instead, on this architectures, SST scheduler lock can be // implemented by temporarily raising the current task priority // to the ceiling level. // /// TBD... static_cast(ceiling); // unused param for now return 0U; #else // ARMv7-M+ // NOTE: // ARMv7-M+ support the BASEPRI register and the selective SST scheduler // locking is implemented by setting BASEPRI to the ceiling level. // uint32_t nvic_prio = ((0xFFU >> nvic_prio_shift) + 1U - ceiling) << nvic_prio_shift; LockKey basepri_; // initialized in the following asm() instruction __asm volatile ("mrs %0,BASEPRI" : "=r" (basepri_) :: ); if (basepri_ > nvic_prio) { // current priority lower than the ceiling? __asm volatile ("cpsid i\n msr BASEPRI,%0\n cpsie i" :: "r" (nvic_prio) : ); } return basepri_; #endif } //............................................................................ void Task::unlock(LockKey lock_key) { #if (__ARM_ARCH == 6) // ARMv6-M? // TBD... static_cast(lock_key); // unused param for now #else // ARMv7-M+ // NOTE: // ARMv7-M+ support the BASEPRI register and the selective SST scheduler // unlocking is implemented by restoring BASEPRI to the lock_key level. // __asm volatile ("msr BASEPRI,%0" :: "r" (lock_key) : ); #endif } } // namespace SST ================================================ FILE: sst_cpp/ports/arm-cm/sst_port.hpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) port to ARM Cortex-M // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #ifndef SST_PORT_HPP_ #define SST_PORT_HPP_ // additional SST-PORT task attributes for ARM Cortex-M #define SST_PORT_TASK_ATTR \ std::uint32_t volatile *m_nvic_pend; \ std::uint32_t m_nvic_irq; // additional SST-PORT task operations for ARM Cortex-M #define SST_PORT_TASK_OPER \ void activate(void); \ void setPrio(TaskPrio prio) noexcept; \ void setIRQ(std::uint32_t irq) noexcept; // SST-PORT critical section #define SST_PORT_CRIT_STAT #define SST_PORT_CRIT_ENTRY() __asm volatile ("cpsid i") #define SST_PORT_CRIT_EXIT() __asm volatile ("cpsie i") // SST-PORT pend the Task after posting an event // NOTE: executed inside SST critical section. // #define SST_PORT_TASK_PEND() *m_nvic_pend = m_nvic_irq namespace SST { void onIdle(void); //! SST lock key using LockKey = std::uint32_t; } #endif // SST_PORT_HPP_ ================================================ FILE: sst_cpp/src/sst.cpp ================================================ //============================================================================ // Super-Simple Tasker (SST/C++) // // Copyright (C) 2006-2023 Quantum Leaps, . // // SPDX-License-Identifier: MIT // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //============================================================================ #include "sst.hpp" // Super-Simple Tasker (SST) in C++ #include "dbc_assert.h" // Design By Contract (DBC) assertions //............................................................................ namespace { // unnamed namespace DBC_MODULE_NAME("sst") // for DBC assertions in this module } // unnamed namespace namespace SST { // SST kernel facilities ----------------------------------------------------- int Task::run(void) { SST::start(); // port-specific start of multitasking onStart(); // configure and start the interrupts for (;;) { // idle loop of the SST kernel onIdle(); } } // SST Task facilities ------------------------------------------------------- void Task::start( TaskPrio prio, Evt const **qBuf, QCtr qLen, Evt const * const ie) { //! @pre //! - the priority must be greater than zero //! - the queue storage and length must be provided DBC_REQUIRE(200, (0U < prio) && (qBuf != nullptr) && (qLen > 0U)); m_qBuf = qBuf; m_end = qLen - 1U; m_head = 0U; m_tail = 0U; m_nUsed = 0U; setPrio(prio); // initialize this task with the initialization event init(ie); // virtual call // TBD: implement event recycling } //............................................................................ void Task::post(Evt const * const e) noexcept { //! @pre the queue must be sized adequately and cannot overflow DBC_REQUIRE(300, m_nUsed <= m_end); SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); m_qBuf[m_head] = e; // insert event into the queue // need to wrap the head? if (m_head == 0U) { m_head = m_end; // wrap around } else { --m_head; } ++m_nUsed; SST_PORT_TASK_PEND(); SST_PORT_CRIT_EXIT(); } //---------------------------------------------------------------------------- static TimeEvt *timeEvt_head = nullptr; //............................................................................ TimeEvt::TimeEvt(Signal sig, Task *task) { this->sig = sig; m_task = task; m_ctr = 0U; m_interval = 0U; // insert this time event into the linked-list m_next = timeEvt_head; timeEvt_head = this; } //............................................................................ void TimeEvt::arm(TCtr ctr, TCtr interval) { SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); m_ctr = ctr; m_interval = interval; SST_PORT_CRIT_EXIT(); } //............................................................................ bool TimeEvt::disarm(void) { SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); bool status = (m_ctr != 0U); m_ctr = 0U; m_interval = 0U; SST_PORT_CRIT_EXIT(); return status; } //............................................................................ void TimeEvt::tick(void) { for (TimeEvt *t = timeEvt_head; t != nullptr; t = t->m_next) { SST_PORT_CRIT_STAT SST_PORT_CRIT_ENTRY(); if (t->m_ctr == 0U) { // disarmed? (most frequent case) SST_PORT_CRIT_EXIT(); } else if (t->m_ctr == 1U) { // expiring? t->m_ctr = t->m_interval; SST_PORT_CRIT_EXIT(); t->m_task->post(t); } else { // timing out --t->m_ctr; SST_PORT_CRIT_EXIT(); } } } } // namespace SST